初学SpringMVC+Mybatis之Spring基于注解的组件扫描

时间:2022-10-25 00:32:01

转自:http://blog.csdn.net/honchen2010/article/details/50984566

1、什么是组件扫描

        指定一个包路径,Spring会自动扫描该包及其子包所有组件类,当发现组件类定义前有特定的注解标记时,就将该组件纳入到Spring容器中,等价于原来的XML配置bean的功能。


2、指定扫描类路径

        使用组件扫描,首先需要在XML配置中指定扫描父级package路径,容器会自动去扫描pers.zky包及其子包下的所有组件,并且实例化bean

[html] view plain copy
  1. <!-- 1、开始扫描,指定扫描的包,此处指定的是pers.zky下面所有子包 -->  
  2. <context:component-scan base-package="pers.zky"></context:component-scan>  


3、自动扫描的注解标记

        指定扫描的类路径后,并且不是所有的该路径下的组件都会被扫描到Spring容器,只有在组件类定义前有以下标记的,才会扫描到Spring容器。

        @Component    通用注解

        @Named            通用注解

        @Respository    持久化层组件注解

        @Service            业务层组件注解

        @Controller        控制层组件注解


4、自动扫描注解命名

        当一个组件在扫描过程中被检测到时,会生成一个默认的id值,默认id值为小写开头的类名,也可以在注解中自定义id。

[java] view plain copy
  1. package pers.zky.entity;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import org.springframework.beans.factory.annotation.Value;  
  6. import org.springframework.stereotype.Component;  
  7. /*@Component//这种注解,扫描时会自动指定其id为首字母小写后的类名,此处即为"book"*/  
  8. @Component("b")//指定注解扫描后的id为"b"  
  9. public class Book implements Serializable{  
  10.     private int id;  
  11.     private String name;  
  12.     public Book(){  
  13.     }  
  14.     public int getId() {  
  15.         return id;  
  16.     }  
  17.     public void setId(int id) {  
  18.         this.id = id;  
  19.     }  
  20.     public String getName() {  
  21.         return name;  
  22.     }  
  23.     public void setName(String name) {  
  24.         this.name = name;  
  25.     }  
  26. }  


[java] view plain copy
  1. @Test  
  2. public void test(){  
  3.     String conf="applicationContext.xml";  
  4.     ApplicationContext ac = new ClassPathXmlApplicationContext(conf);  
  5.     /** 
  6.      * Book实体类使用的是注解注入没有指定类的id时 
  7.      * Spring规定了注解注入经过组件扫描后,其id为类名首字母小写后的名字 
  8.      */  
  9.     /*Book book = ac.getBean("book",Book.class);*/  
  10.     Book book = ac.getBean("b",Book.class);  
  11.   
  12.     System.out.println(book);//pers.zky.entity.Book@1738a82  
  13.     System.out.println(book.getId());//0  
  14.     System.out.println(book.getName());//null  


5、指定组件的作用域

        通常Spring管理的组件,默认的作用域是"singleton",如果需要其他的作用域也可以使用@Scope注解,只要在注解中提供作用域的名称即可。

[java] view plain copy
  1. package pers.zky.entity;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import org.springframework.context.annotation.Scope;  
  6. import org.springframework.stereotype.Component;  
  7.   
  8. /** 
  9.  * @author Zky 
  10.  * 
  11.  */  
  12. @Scope("prototype")  
  13. @Component("student")  
  14. public class Student implements Serializable{  
  15.     private String name;  
  16.     private int id;  
  17.     private Book book;  
  18.     public Student(){     
  19.     }  
  20.     public String getName() {  
  21.         return name;  
  22.     }  
  23.     public void setName(String name) {  
  24.         this.name = name;  
  25.     }  
  26.     public int getId() {  
  27.         return id;  
  28.     }  
  29.     public void setId(int id) {  
  30.         this.id = id;  
  31.     }  
  32.     public Book getBook() {  
  33.         return book;  
  34.     }  
  35. }  

[java] view plain copy
  1. Student stu  = ac.getBean("student",Student.class);  
  2. Student stu1 = ac.getBean("student",Student.class);  
  3. System.out.println(stu==stu1);//false,未指定Scope的属性时默认为sington,输出为true  


6、指定初始化和销毁方法

        @PostConstruct 指定初始化方法

        @PreDestroy 指定销毁方法

[java] view plain copy
  1. @PostConstruct//指定初始化方法  
  2. public void init(){  
  3.     System.out.println("student初始化");  
  4. }  
  5. @PreDestroy//指定销毁方法  
  6. public void destroy(){  
  7.     System.out.println("student销毁");  
  8. }  


7、指定依赖注入关系

        具有依赖关系的bean对象,利用下面任意一种注解都可以实现关系的注入。

        1)、基本类型的值注入可以使用 @value() 标记

[java] view plain copy
  1. package pers.zky.entity;  
  2.   
  3. import java.io.Serializable;  
  4.   
  5. import org.springframework.beans.factory.annotation.Value;  
  6. import org.springframework.stereotype.Component;  
  7.   
  8. @Component("b")  
  9. public class Book implements Serializable{  
  10.     @Value("10001")  
  11.     private int id;  
  12.     @Value("西游记")  
  13.     private String name;  
  14.     public Book(){  
  15.     }  
  16.     public int getId() {  
  17.         return id;  
  18.     }  
  19.     public void setId(int id) {  
  20.         this.id = id;  
  21.     }  
  22.     public String getName() {  
  23.         return name;  
  24.     }  
  25.     public void setName(String name) {  
  26.         this.name = name;  
  27.     }  
  28. }  


        2)、@Autowired/@Qualifier可以处理构造器注入和Setter注入

        @Autowired写在构造器前面,申明需要为其注入bean。

        @Qualifier写在参数前面,申明需要注入的bean的id,注入对象单例时,@Qualifier可以省略。

        @Autowired写在属性上面,只会执行构造器的赋值语句,其他代码不会执行。

[java] view plain copy
  1. package pers.zky.entity;  
  2. import java.io.Serializable;  
  3. import org.springframework.beans.factory.annotation.Autowired;  
  4. import org.springframework.beans.factory.annotation.Value;  
  5. import org.springframework.stereotype.Component;  
  6. /** 
  7.  * @author Zky 
  8.  */  
  9. @Component("student")  
  10. public class Student implements Serializable{  
  11.     @Value("张三")  
  12.     private String name;  
  13.     @Value("1001")  
  14.     private int id;  
  15.     @Autowired  
  16.     private Book book;  
  17.     public Student(){     
  18.     }  
  19.     public Student(Book book){  
  20.         System.out.println("before");  
  21.         this.book = book;  
  22.         System.out.println("after");  
  23.     }     
  24.     public String getName() {  
  25.         return name;  
  26.     }  
  27.     public void setName(String name) {  
  28.         this.name = name;  
  29.     }  
  30.     public int getId() {  
  31.         return id;  
  32.     }  
  33.     public void setId(int id) {  
  34.         this.id = id;  
  35.     }  
  36.     public Book getBook() {  
  37.         return book;  
  38.     }  
  39.     public void setBook(Book book) {  
  40.         System.out.println("before_getbook");  
  41.         this.book = book;  
  42.         System.out.println("after_getbook");  
  43.     }  
  44. }  

[java] view plain copy
  1. @Test  
  2. public void test(){  
  3.     String conf="applicationContext.xml";  
  4.     ApplicationContext ac = new ClassPathXmlApplicationContext(conf);  
  5.     Student stu  = ac.getBean("student",Student.class);  
  6.     System.out.println(stu.getBook().getName());  
  7. }  
  8.   
  9. Console:  
  10. 西游记  

        @Autowired写在构造方法或者set方法上时,会执行里面全部的代码。下面是Student类的@Autowired改写到构造器或者set方法上后的输出结果,Test方法和上面一样。

[java] view plain copy
  1. @Autowired  
  2. public Student(Book book){  
  3.     System.out.println("before");  
  4.     this.book = book;  
  5.     System.out.println("after");  
  6. }  
  7.   
  8. Console:  
  9. before  
  10. after  
  11. 西游记  

[java] view plain copy
  1. <pre name="code" class="java">@Autowired  
  2. public void setBook(Book book){  
  3.     System.out.println("before_setbook");  
  4.     this.book = book;  
  5.     System.out.println("after_setbook");  
  6. }  
  7.   
  8. Console:  
  9. before_setbook  
  10. after_setbook  
  11. 西游记  

 

        3)、使用@Resouce注解

        只能用在属性和set方法上上。

        用在set 方法中 ,执行所有的方法体。

        用在属性上只执行方法的赋值。

        @Resouce写在构造器上会报语法错误:The annotation @Resource is disallowed for this location

        同样使用上面的例子,删掉@Autowired注解,使用@Resouce注解set方法和属性:

[java] view plain copy
  1. @Resource  
  2. private Book book;  
  3.   
  4. Console:  
  5. 西游记  

[java] view plain copy
  1. <pre name="code" class="java">@Resource  
  2. public void setBook(Book book) {  
  3.     System.out.println("before_setbook");  
  4.     this.book = book;  
  5.     System.out.println("after_setbook");  
  6. }  
  7.   
  8. Console:  
  9. before_setbook  
  10. after_setbook  
  11. 西游记  

 

        Setter注入推荐使用@Resource,构造器推荐使用@Autowired。

        4)、注入spring的表达式

        将db.properties至于src文件目录下,其内容如下:

[plain] view plain copy
  1. username=scott  
  2. password=scott  
  3. jdbc=jdbc:oracle:thin:localhost:1521:orcl  
  4. driver=oracle.jdbc.OracleDriver  

        声明properties集合,读取参数:

[html] view plain copy
  1. <util:properties id="jdbc" location="classpath:db.properties"></util:properties>  

        编写实体类,用spring表达式注入值:

[java] view plain copy
  1. package pers.zky.entity;  
  2. import java.io.Serializable;  
  3. import org.springframework.beans.factory.annotation.Value;  
  4. import org.springframework.stereotype.Component;  
  5. @Component  
  6. public class JdbcOracle implements Serializable{  
  7.     @Value("#{jdbc.username}")  
  8.     private String username;  
  9.     @Value("#{jdbc.password}")  
  10.     private String password;  
  11.     @Value("#{jdbc.url}")  
  12.     private String url;  
  13.     @Value("#{jdbc.driver}")  
  14.     private String driver;  
  15.     public JdbcOracle(){  
  16.     }  
  17.     public String getUsername() {  
  18.         return username;  
  19.     }  
  20.     public void setUsername(String username) {  
  21.         this.username = username;  
  22.     }  
  23.     public String getPassword() {  
  24.         return password;  
  25.     }  
  26.     public void setPassword(String password) {  
  27.         this.password = password;  
  28.     }  
  29.     public String getUrl() {  
  30.         return url;  
  31.     }  
  32.     public void setUrl(String url) {  
  33.         this.url = url;  
  34.     }  
  35.     public String getDriver() {  
  36.         return driver;  
  37.     }  
  38.     public void setDriver(String driver) {  
  39.         this.driver = driver;  
  40.     }  
  41. }  

        编写测试方法,输出结果:

[java] view plain copy
  1. @Test  
  2. public void test(){  
  3.     String conf="applicationContext.xml";  
  4.     ApplicationContext ac = new ClassPathXmlApplicationContext(conf);  
  5.     JdbcOracle jdbcOracle = ac.getBean("jdbcOracle",JdbcOracle.class);  
  6.     System.out.println(jdbcOracle.getUsername());  
  7.     System.out.println(jdbcOracle.getPassword());  
  8.     System.out.println(jdbcOracle.getUrl());  
  9.     System.out.println(jdbcOracle.getDriver());  
  10. }  
  11.   
  12. Console:  
  13. scott  
  14. scott  
  15. jdbc:oracle:thin:localhost:1521:orcl  
  16. oracle.jdbc.OracleDriver