zoukankan      html  css  js  c++  java
  • Spring 自动装配及其注解

    https://blog.csdn.net/zcywell/article/details/88397158

    一.属性自动装配

     首先,准备三个类,分别是User,Cat,Dog。其中User属性拥有Cat和Dog对象。

    复制代码

     1 package com.hdu.autowire;
     2 
     3 public class User {
     4     private Cat cat;
     5     private Dog dog;
     6     private String str;
     7     
     8     public Cat getCat() {
     9         return cat;
    10     }
    11     public void setCat(Cat cat) {
    12         this.cat = cat;
    13     }
    14     public Dog getDog() {
    15         return dog;
    16     }
    17     public void setDog(Dog dog) {
    18         this.dog = dog;
    19     }
    20     public String getStr() {
    21         return str;
    22     }
    23     public void setStr(String str) {
    24         this.str = str;
    25     }
    26 }

    复制代码

    复制代码

    1 package com.hdu.autowire;
    2 
    3 public class Cat {
    4     public void shout() {
    5         System.out.println("miao~");
    6     }
    7 }

    复制代码

    复制代码

    1 package com.hdu.autowire;
    2 
    3 public class Dog {
    4     public void shout() {
    5         System.out.println("wang~");
    6     }
    7 }

    复制代码

     测试代码:

    复制代码

     1 package com.hdu.test;
     2 
     3 import org.junit.Test;
     4 import org.springframework.context.ApplicationContext;
     5 import org.springframework.context.support.ClassPathXmlApplicationContext;
     6 
     7 public class TestIOCDI {
     8     @Test
     9     public void testMethodAutowire() {
    10         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_autowire.xml");
    11         com.hdu.autowire.User user = context.getBean("user", com.hdu.autowire.User.class);
    12         user.getCat().shout();
    13         user.getDog().shout();
    14     }
    15 }

    复制代码

        1.1 xml配置文件

    复制代码

    <bean id="cat" class="com.hdu.autowire.Cat"></bean>
    <bean id="dog" class="com.hdu.autowire.Dog"></bean>
        
    <bean id="user" 
              class="com.hdu.autowire.User">
        <property name="cat" ref="cat"></property>
        <property name="dog" ref="dog"></property>
        <property name="str" value="haha"></property>
    </bean>

    复制代码

        1.2 autowire byName (按名称自动装配)

            由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。采用自动装配将避免这些错误,并且使配置简单化。

      当一个bean节点带有 autowire byName的属性时。

        ①将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。

        ②去spring容器中寻找是否有此字符串名称id的对象。

        ③如果有,就取出注入;如果没有,就报空指针异常。

    复制代码

    <bean id="cat" class="com.hdu.autowire.Cat"></bean>
    <bean id="dog" class="com.hdu.autowire.Dog"></bean>
        
    <bean id="user" 
          class="com.hdu.autowire.User"
          autowire="byName">
    </bean>

    复制代码

            如果将 <bean id="cat" class="com.hdu.autowire.Cat"></bean> 改成

    <bean id="catXXX" class="com.hdu.autowire.Cat"></bean>

            执行时报空指针java.lang.NullPointerException。因为按byName规则找不对应set方法,真正的setCat就没执行,对象就没有初始化,所以调用时就会报空指针错误。

        1.3autowire byType (按类型自动装配)

            使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常。

    复制代码

    <bean id="cat" class="com.hdu.autowire.Cat"></bean>
    <bean id="dog" class="com.hdu.autowire.Dog"></bean>
        
    <bean id="user" 
          class="com.hdu.autowire.User"
          autowire="byType">
    </bean>

    复制代码

            将<bean id="cat" class="com.hdu.autowire.Cat"></bean> 改成

    <bean id="catXXX" class="com.hdu.autowire.Cat"></bean>

            因为是按类型装配,所以并不会报异常,也不影响最后的结果。

            甚至将id属性去掉,也不影响结果。

    <bean class="com.hdu.autowire.Cat"></bean>

        1.4全局autowire

    复制代码

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:util="http://www.springframework.org/schema/util" 
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/util 
            http://www.springframework.org/schema/util/spring-util.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd"  default-autowire="byName">
            
        <bean id="cat" class="com.hdu.autowire.Cat"></bean>
        <bean id="dog" class="com.hdu.autowire.Dog"></bean>
        
        <bean id="user" class="com.hdu.autowire.User" autowire="default"/>
        <bean id="user2" class="com.hdu.autowire.User" autowire="default"/>
        <bean id="user3" class="com.hdu.autowire.User" autowire="default"/>
    
    </beans>

    复制代码

    二.属性注解

        jdk1.5开始支持注解,spring2.5开始全面支持注解。

        利用注解的方式注入属性。

        ①spring引入context文件头

        ②开启属性注解

    复制代码

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:util="http://www.springframework.org/schema/util"  xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop.xsd
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx.xsd
            http://www.springframework.org/schema/util 
            http://www.springframework.org/schema/util/spring-util.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc.xsd">
            
        <context:annotation-config/>
    </beans>

    复制代码

        2.1 @Autowired

            @Autowired是按类型自动转配的,不支持id匹配。

            将User中的set方法去掉,加入@Autowired注解。

            其中这里依赖一个的jar包。

    复制代码

     1 package com.hdu.autowire;
     2 
     3 import org.springframework.beans.factory.annotation.Autowired;
     4 
     5 public class User {
     6     @Autowired
     7     private Cat cat;
     8     @Autowired
     9     private Dog dog;
    10     private String str;
    11     
    12     public Cat getCat() {
    13         return cat;
    14     }
    15     
    16     public Dog getDog() {
    17         return dog;
    18     }
    19     
    20     public String getStr() {
    21         return str;
    22     }
    23 }

    复制代码

    <context:annotation-config/>
        
    <bean id="catXXX" class="com.hdu.autowire.Cat"></bean>
    <bean id="dogXXX" class="com.hdu.autowire.Dog"></bean>
        
    <bean id="user" class="com.hdu.autowire.User"></bean>

        @Autowired(required=false)   

        false,对象可以为null;true,对象必须存对象,不能为null。

        2.2 @Qualifier

            @Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配,其中@Qualifier不能单独使用。

    复制代码

     1 package com.hdu.autowire;
     2 
     3 import org.springframework.beans.factory.annotation.Autowired;
     4 import org.springframework.beans.factory.annotation.Qualifier;
     5 
     6 public class User {
     7     @Autowired
     8     @Qualifier(value="carXXX")
     9     private Cat cat;
    10     @Autowired
    11     @Qualifier(value="dogXXX")
    12     private Dog dog;
    13     private String str;
    14     
    15     public Cat getCat() {
    16         return cat;
    17     }
    18     
    19     public Dog getDog() {
    20         return dog;
    21     }
    22     
    23     public String getStr() {
    24         return str;
    25     }
    26 }

    复制代码

        2.3 @Resource

        @Resource如有指定的name属性,先按该属性进行byName方式查找装配;其次再进行默认的byName方式进行装配;如果以上都不成功,则按byType的方式自动装配。都不成功,则报异常。

    复制代码

     1 package com.hdu.autowire;
     2 
     3 import javax.annotation.Resource;
     4 
     5 public class User {
     6     @Resource
     7     private Cat cat;
     8     @Resource(name="dogXXX")
     9     private Dog dog;
    10     private String str;
    11     
    12     public Cat getCat() {
    13         return cat;
    14     }
    15     
    16     public Dog getDog() {
    17         return dog;
    18     }
    19     
    20     public String getStr() {
    21         return str;
    22     }
    23 }

    复制代码

    配置文件1:

    <bean id="catXXX" class="com.hdu.autowire.Cat"></bean>
    <bean id="cat" class="com.hdu.autowire.Cat"></bean>
    <bean id="dogXXX" class="com.hdu.autowire.Dog"></bean>
        
    <bean id="user" class="com.hdu.autowire.User"></bean>

      先进行byName查找,成功。

    配置文件2:

    <context:annotation-config/> 
        
    <bean id="catXXX" class="com.hdu.autowire.Cat"></bean>
    <bean id="dogXXX" class="com.hdu.autowire.Dog"></bean>
        
    <bean id="user" class="com.hdu.autowire.User"></bean>

        先进行byName查找,失败;再进行byType查找,成功。

    配置文件3:

    <bean id="catXXX" class="com.hdu.autowire.Cat"></bean>
    <bean id="catYYY" class="com.hdu.autowire.Cat"></bean>
    <bean id="dogXXX" class="com.hdu.autowire.Dog"></bean>
        
    <bean id="user" class="com.hdu.autowire.User"></bean>

    先进行byName查找,失败;再进行byType查找,有两个匹配,失败,报错。

        2.4小结:

        @Autowired与@Resource异同:

        1° @Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。

        2° @Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用。

        3° @Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。 当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

    它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName。

    三.类自动装配

        3.1 包扫描

        注解替换bean节点
            @Controller注解       只能用控制器类上
            @Service注解           只能用在业务类上
            @Repository注解      只能用在dao类上
            @Component注解     无法按照上面三个注解分类,就用此注解 

    复制代码

     1 package com.hdu.autowire;
     2 
     3 import org.springframework.stereotype.Component;
     4 
     5 @Component
     6 public class Cat {
     7     public void shout() {
     8         System.out.println("miao~");
     9     }
    10 }

    复制代码

    复制代码

     1 package com.hdu.autowire;
     2 
     3 import org.springframework.stereotype.Component;
     4 
     5 @Component
     6 public class Dog {
     7     public void shout() {
     8         System.out.println("wang~");
     9     }
    10 }

    复制代码

    复制代码

     1 package com.hdu.autowire;
     2 
     3 import javax.annotation.Resource;
     4 import org.springframework.stereotype.Component;
     5 
     6 @Component
     7 public class User {
     8     @Resource
     9     private Cat cat;
    10     @Resource
    11     private Dog dog;
    12     private String str;
    13     
    14     public Cat getCat() {
    15         return cat;
    16     }
    17     
    18     public Dog getDog() {
    19         return dog;
    20     }
    21     
    22     public String getStr() {
    23         return str;
    24     }
    25 }

    复制代码

    复制代码

    <!-- 解析注解
         @Controller
         @Service
         @Repository
         @Component
         component-scan:组件扫描
         base-package:基本包,指定包名,多个包名可以用逗号间隔
         也可以写多个<context:component-scan
         如果用了组件扫描后<context:annotation-config></context:annotation-config>就不用写了,组件扫描已经包含了 <context:annotation-config>
    -->
    <context:component-scan base-package="com.hdu.autowire"/>

    复制代码

    测试:

    复制代码

     1 package com.hdu.test;
     2 
     3 import org.junit.Test;
     4 import org.springframework.context.ApplicationContext;
     5 import org.springframework.context.support.ClassPathXmlApplicationContext;
     6 
     7 import com.hdu.autowire.User;
     8 
     9 public class TestIOCDI {
    10     @Test
    11     public void testMethodAutowire() {
    12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_autowire.xml");
    13         User user = context.getBean("user", User.class);
    14         user.getCat().shout();
    15         user.getDog().shout();
    16     }
    17 }

    复制代码

        3.2 类目和ID对应表:

            类名:    CAT        cAT         CaT        caT

            ID:          CAT         cAT        caT         caT

        分析:类名的关键在于第二个字母,第二个字母大写,首字母大写小写无所谓。如果第二个字母小写,那第一个必须小写。第二个字母之后大小写没关系。

                   如果没有指定value,spring容器中id规则,是类名的首字母小写。

        3.3 自定义bean的id

            @Component(value="cat")

    四.其它注解

        4.1 @Value

    jdbc_driverClass=com.mysql.jdbc.Driver
    jdbc_url=jdbc:mysql://localhost:3306/tmpdb
    jdbc_userName=root
    jdbc_userPassword=root

            4.1.1${}表达式

    <context:component-scan base-package="com.hdu.util"></context:component-scan>
    <!-- 用$表达式方式 -->
    <context:property-placeholder location="classpath:/resources/mysql.properties"/>

    复制代码

     1 package com.hdu.util;
     2 
     3 import org.springframework.beans.factory.annotation.Value;
     4 import org.springframework.stereotype.Component;
     5 
     6 @Component("jdbcUtil")
     7 public class JDBCUtil {
     8     @Value("${jdbc_driverClass}")
     9     private String driverClass;
    10     @Value("${jdbc_url}")
    11     private String url;
    12     @Value("${jdbc_userName}")
    13     private String userName;
    14     @Value("${jdbc_userPassword}")
    15     private String password;
    16     public String getDriverClass() {
    17         return driverClass;
    18     }
    19     
    20     public String getUrl() {
    21         return url;
    22     }
    23     
    24     public String getUserName() {
    25         return userName;
    26     }
    27     
    28     public String getPassword() {
    29         return password;
    30     }
    31     
    32     @Override
    33     public String toString() {
    34         return "JDBCUtil [driverClass=" + driverClass + ", url=" + url + ", userName=" + userName + ", password="
    35                 + password + "]";
    36     }
    37     
    38     
    39     
    40 }

    复制代码

    测试:

    复制代码

     1 package com.hdu.test;
     2 
     3 import org.junit.Test;
     4 import org.springframework.context.ApplicationContext;
     5 import org.springframework.context.support.ClassPathXmlApplicationContext;
     6 
     7 import com.hdu.util.JDBCUtil;
     8 
     9 public class TestSpringIOCDI_Annoation {
    10     @Test
    11     public void testMethod() {
    12         ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_annotation.xml");
    13         JDBCUtil jdbcUtil = context.getBean("jdbcUtil", JDBCUtil.class);
    14         System.out.println(jdbcUtil);
    15     }
    16 }

    复制代码

            4.1.2#{}表达式

    <context:component-scan base-package="com.hdu.util"></context:component-scan>
    <!-- 用#表达式方式 -->
    <util:properties id="manyProperty" location="classpath:/resources/mysql.properties"></util:properties>

    复制代码

     1 package com.hdu.util;
     2 
     3 import org.springframework.beans.factory.annotation.Value;
     4 import org.springframework.stereotype.Component;
     5 
     6 @Component("jdbcUtil1")
     7 public class JDBCUtil1 {//@Value("#{manyProperty['jdbc_url']}")
     8     @Value("#{manyProperty.jdbc_driverClass}")
     9     private String driverClass;
    10     @Value("#{manyProperty.jdbc_url}")
    11     private String url;
    12     @Value("#{manyProperty.jdbc_userName}")
    13     private String userName;
    14     @Value("#{manyProperty.jdbc_userPassword}")
    15     private String password;
    16     public String getDriverClass() {
    17         return driverClass;
    18     }
    19     
    20     public String getUrl() {
    21         return url;
    22     }
    23     
    24     public String getUserName() {
    25         return userName;
    26     }
    27     
    28     public String getPassword() {
    29         return password;
    30     }
    31     
    32     @Override
    33     public String toString() {
    34         return "JDBCUtil [driverClass=" + driverClass + ", url=" + url + ", userName=" + userName + ", password="
    35                 + password + "]";
    36     }
    37 
    38 }

    复制代码

    测试:

    复制代码

    package com.hdu.test;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.hdu.util.JDBCUtil1;
    
    public class TestSpringIOCDI_Annoation {
        @Test
        public void testMethod() {
            //加载spring容器
            ApplicationContext context = new ClassPathXmlApplicationContext("resources/spring_annotation.xml");
            //从spring容器中取出对象
            JDBCUtil1 jdbcUtil = context.getBean("jdbcUtil1", JDBCUtil1.class);
            System.out.println(jdbcUtil);
        }
    }

    复制代码

        4.2 @Scope(value="prototype")// 单例和多例 修饰在类上 

        4.3 @Lazy //代表懒加载 修饰在类上 

        4.4 @PostConstruct //表示初始化操作 修饰在方法上

        4.5 @PreDestroy //表示销毁 修饰在方法上

  • 相关阅读:
    cf1108E2 线段树类似扫描线
    poj1185 状态压缩经典题
    cf1110F 离线+树上操作+线段树区间更新
    tarjan求lca :并查集+dfs
    cf1110E 思维
    cf1110d 线性dp
    cf842D 01字典树|线段树 模板见hdu4825
    cf842C 树形dp+gcd函数
    cf581F 依赖背包+临时数组 好题
    hdu5758 思维,树形dp
  • 原文地址:https://www.cnblogs.com/yangyanbo/p/12368883.html
Copyright © 2011-2022 走看看