博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring 自动装配及其注解
阅读量:6970 次
发布时间:2019-06-27

本文共 18069 字,大约阅读时间需要 60 分钟。

一.属性自动装配

 首先,准备三个类,分别是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配置文件

 

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

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

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

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

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

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

        如果将 <bean id="cat" 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> 改成

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

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

 

    1.4全局autowire

 

二.属性注解

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

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

    ①spring引入context文件头

    ②开启属性注解

 

    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 }

    @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     @Autowired11     @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:

  先进行byName查找,成功。

 

配置文件2:

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

 

配置文件3:

先进行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     @Resource11     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 }

测试:

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     @Test11     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.Driverjdbc_url=jdbc:mysql://localhost:3306/tmpdbjdbc_userName=rootjdbc_userPassword=root

        4.1.1${}表达式

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     @Override33     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     @Test11     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#{}表达式

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 @Override33 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 //表示销毁 修饰在方法上

一.属性自动装配

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

 
Class User
 
Class Cat
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配置文件

 

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

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

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

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

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

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

        如果将 <bean id="cat" 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> 改成

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

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

 

    1.4全局autowire

 

二.属性注解

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

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

    ①spring引入context文件头

    ②开启属性注解

 

    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 }

    @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     @Autowired11     @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:

  先进行byName查找,成功。

 

配置文件2:

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

 

配置文件3:

先进行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注解     无法按照上面三个注解分类,就用此注解 

 
Class Cat
 
Class Dog
 
Class User

测试:

 
Test

 

    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.Driverjdbc_url=jdbc:mysql://localhost:3306/tmpdbjdbc_userName=rootjdbc_userPassword=root

        4.1.1${}表达式

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     @Override33     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     @Test11     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#{}表达式

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 @Override33 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 //表示销毁 修饰在方法上

转载于:https://www.cnblogs.com/cxhfuujust/p/10561394.html

你可能感兴趣的文章
讲座:计算机专业及其学习
查看>>
CentOS 7 启动、重启、chkconfig等命令已经合并为systemctl
查看>>
POI 中的CellRangeAddress 参数
查看>>
Http Request
查看>>
Map集合中value()方法与keySet()、entrySet()区别 《转》
查看>>
Thrift反序列化导致OOM(转)
查看>>
自定义用户登录,会话保持,登录后自动跳转原页面
查看>>
Quartz的cronTrigger表达式
查看>>
李洪强经典iOS面试题11
查看>>
知乎上关于游戏引擎的讨论
查看>>
解决:error: Cannot fetch repo (TypeError: expected string or buffer)
查看>>
oracle 11g RAC 的一些基本概念(三)
查看>>
api数据接口
查看>>
买房的贷款时间是否是越长越好?https://www.zhihu.com/question/20842791
查看>>
maven整合S2SH
查看>>
Android 增量更新完全解析 是增量不是热修复
查看>>
UI设计中px、pt、ppi、dpi、dp、sp之间的关系
查看>>
atitit 短信验证码的源码实现 .docx
查看>>
学位论文“致谢”中的人称问题
查看>>
JavaScript面向对象
查看>>