让Spring自动扫描和管理Bean
2010-06-23 12:30
411 查看
通过在classpath自动扫描方式把组件纳入spring容器中管理
----------------------------------------------------------------------
为什么我们要使用类路径扫描的方式把组件纳入Spring容器中管理呢?前面的例子我们都是使用XML的bean定义来配置组件。尽管我们使用了依赖注入的注解减少了属性的注入配置,但是还是避免不了在配置文件中定义大量的bean,在一个稍大的项目中,通常会有上百个组件,如果这些这组件采用xml的bean定义来配置,显然会增加配置文件的体积,配置文件会很臃肿,查找及维护起来也不太方便。spring2.5为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息:
Xml代码
首先要引入context命名空间,接着要打开主键扫描<context:component-scan/>这个配置项
其中base-package为需要扫描的包(含子包),就是说我们要扫描哪个包下面的类,这里要注意它除了会扫描你指定包下的类,还会扫描这个包底下子包的类。
那么扫描这些类,Spring怎么知道这些类要交给Spring管理呢?这时候,我们用到了注解。spring2.5为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。
@Service用于标注业务层组件、 @Controller用于标注控制层组件(如struts中的action)、@Repository用于标注数据访问组件,即DAO组件。而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
这四个注解目前作用都是一样的,因为目前Spring还没对这几个注解进行特别的处理,随便标哪个注解在目前都是一样的。当然可能以后会有一些细微的变化,目前还没做到这一点。
beans.xml
Xml代码
在beans.xml配置文件里,发现很干净,只是打开了配置项
PersonDaoBean.java
Java代码
PersonServiceBean.java
Java代码
SpringTest.java
Java代码
如果输出为null,则代表没被管理。
运行单元测试代码,控制台输出:
cn.itcast.service.impl.PersonServiceBean@be0e27
cn.itcast.dao.impl.PersonDaoBean@193385d
对象已经获取到了,我们采用的是Spring自动扫描的方式把bean交给了Spring管理,采用这种方式,以后就不需要在beans.xml配置文件配置大量的bean,不需要了,这样就把开发人员从配置文件中解脱出来了,这个功能很有用哈,这也是为什么Spring2.5推出来的原因,它提供了一些更便于开发的新功能,这个注解采用扫描的方式就是他推出的一个新特点
有同学现在就可能有些想法了,默认值是bean的名称,首字母小写,那么能改么? Spring当然能提供这种修改途径
PersonServiceBean.java
Java代码
运行单元测试代码,输出
cn.itcast.service.impl.PersonServiceBean@be0e27
cn.itcast.dao.impl.PersonDaoBean@193385d
就是说,可以通过personService这个名称得到这个bean,这里,大家就学会了怎样修改bean的名称。
这时候同学又有疑问了,bean的作用域范围有好几种啊(单例,原型prototype),目前到底是属于哪种作用域范围呢?是单例。 如果想把它改为原型prototype怎么办? 就要通过另一个注解@Scope
PersonServiceBean.java
Java代码
SpringTest.java
Java代码
如果打印false,则证明配置是成功的
运行单元测试代码,打印结果是false
所以通过@Scope这个注解,就可以修改bean的作用域。
这时候同学们有没有想到另一个问题? 原先我们在beans.xml里使用bean配置的时候,我们可以指定初始化init-method方法,和销毁destroy-method方法.这里怎么办呢? 我们可以使用注解的方式来指定初始化方法和销毁方法
PersonServiceBean.java
Java代码
beans.xml
Xml代码
SpringTest.java
Java代码
运行单元测试代码,输出
初始化
关闭资源
这里已经给大家介绍完了怎样采用扫描的方式来把组件交给Spring管理,这种方式是我们目前在新开发应用中大量使用的方式,以前的应用中这种方式是没有这种功能的,以前采用Spring2.0是没有这种功能的,这个功能是2.5推出的,这个功能一推出,确实是被很多的新开发的项目所采用,因为这种方式确实是太方便了,能够大大提高我们的开发效率
----------------------------------------------------------------------
为什么我们要使用类路径扫描的方式把组件纳入Spring容器中管理呢?前面的例子我们都是使用XML的bean定义来配置组件。尽管我们使用了依赖注入的注解减少了属性的注入配置,但是还是避免不了在配置文件中定义大量的bean,在一个稍大的项目中,通常会有上百个组件,如果这些这组件采用xml的bean定义来配置,显然会增加配置文件的体积,配置文件会很臃肿,查找及维护起来也不太方便。spring2.5为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息:
Xml代码
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:component-scan base-package="cn.itcast"/> </beans>
首先要引入context命名空间,接着要打开主键扫描<context:component-scan/>这个配置项
其中base-package为需要扫描的包(含子包),就是说我们要扫描哪个包下面的类,这里要注意它除了会扫描你指定包下的类,还会扫描这个包底下子包的类。
那么扫描这些类,Spring怎么知道这些类要交给Spring管理呢?这时候,我们用到了注解。spring2.5为我们引入了组件自动扫描机制,他可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进spring容器中管理。它的作用和在xml文件中使用bean节点配置组件是一样的。
@Service用于标注业务层组件、 @Controller用于标注控制层组件(如struts中的action)、@Repository用于标注数据访问组件,即DAO组件。而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。
这四个注解目前作用都是一样的,因为目前Spring还没对这几个注解进行特别的处理,随便标哪个注解在目前都是一样的。当然可能以后会有一些细微的变化,目前还没做到这一点。
beans.xml
Xml代码
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:component-scan base-package="cn.itcast"/> </beans>
在beans.xml配置文件里,发现很干净,只是打开了配置项
PersonDaoBean.java
Java代码
package cn.itcast.dao.impl; import org.springframework.stereotype.Repository; import cn.itcast.dao.PersonDao; @Repository //这个注解告诉Spring,PersonDaoBean这个类现在要交给Spring管理,Spring扫描到 //这个类之后就知道它要把这个类纳入到Spring容器中管理 public class PersonDaoBean implements PersonDao { public void add(){ System.out.println("执行了PersonDaoBean中的add()方法"); } }
PersonServiceBean.java
Java代码
package cn.itcast.service.impl; import org.springframework.stereotype.Service; import cn.itcast.dao.PersonDao; import cn.itcast.service.PersonService; @Service //当Spring扫描到这个类之后就知道它要把这个类纳入到Spring容器中管理,而且它是作为服务层组件的 public class PersonServiceBean implements PersonService { private PersonDao personDao; public void setPersonDao(PersonDao personDao) { this.personDao = personDao; } public void save(){ personDao.add(); } }
SpringTest.java
Java代码
package junit.test; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.itcast.service.PersonService; public class SpringTest { @BeforeClass public static void setUpBeforeClass() throws Exception { } @Test public void instanceSpring(){ AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); PersonService personService = (PersonService)ctx.getBean("personService"); System.out.println(personService); ctx.close(); } }
如果输出为null,则代表没被管理。
运行单元测试代码,控制台输出:
cn.itcast.service.impl.PersonServiceBean@be0e27
cn.itcast.dao.impl.PersonDaoBean@193385d
对象已经获取到了,我们采用的是Spring自动扫描的方式把bean交给了Spring管理,采用这种方式,以后就不需要在beans.xml配置文件配置大量的bean,不需要了,这样就把开发人员从配置文件中解脱出来了,这个功能很有用哈,这也是为什么Spring2.5推出来的原因,它提供了一些更便于开发的新功能,这个注解采用扫描的方式就是他推出的一个新特点
有同学现在就可能有些想法了,默认值是bean的名称,首字母小写,那么能改么? Spring当然能提供这种修改途径
PersonServiceBean.java
Java代码
package cn.itcast.service.impl; import org.springframework.stereotype.Service; import cn.itcast.dao.PersonDao; import cn.itcast.service.PersonService; @Service("personService") //当Spring扫描到这个类之后就知道它要把这个类纳入到Spring容器中管理,而且它是作为服务层组件的 //可以通过personService这个名称获取这个bean了 public class PersonServiceBean implements PersonService { private PersonDao personDao; public void setPersonDao(PersonDao personDao) { this.personDao = personDao; } public void save(){ personDao.add(); } }
运行单元测试代码,输出
cn.itcast.service.impl.PersonServiceBean@be0e27
cn.itcast.dao.impl.PersonDaoBean@193385d
就是说,可以通过personService这个名称得到这个bean,这里,大家就学会了怎样修改bean的名称。
这时候同学又有疑问了,bean的作用域范围有好几种啊(单例,原型prototype),目前到底是属于哪种作用域范围呢?是单例。 如果想把它改为原型prototype怎么办? 就要通过另一个注解@Scope
PersonServiceBean.java
Java代码
package cn.itcast.service.impl; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; import cn.itcast.dao.PersonDao; import cn.itcast.service.PersonService; @Service("personService") //当Spring扫描到这个类之后就知道它要把这个类纳入到Spring容器中管理,而且它是作为服务层组件的 //可以通过personService这个名称获取这个bean了 @Scope("prototype") //每调用一次getBean方法,都会返回一个新的实例 public class PersonServiceBean implements PersonService { private PersonDao personDao; public void setPersonDao(PersonDao personDao) { this.personDao = personDao; } public void save(){ personDao.add(); } }
SpringTest.java
Java代码
package junit.test; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.itcast.dao.impl.PersonDaoBean; import cn.itcast.service.PersonService; public class SpringTest { @BeforeClass public static void setUpBeforeClass() throws Exception { } @Test public void instanceSpring() { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); PersonService personService1 = (PersonService) ctx.getBean("personService"); // 关于bean的名称,这里有条默认的规则,就是类的名称,然后第一个字母小写 PersonService personService2 = (PersonService) ctx.getBean("personService"); System.out.println(personService1 == personService2); ctx.close(); } }
如果打印false,则证明配置是成功的
运行单元测试代码,打印结果是false
所以通过@Scope这个注解,就可以修改bean的作用域。
这时候同学们有没有想到另一个问题? 原先我们在beans.xml里使用bean配置的时候,我们可以指定初始化init-method方法,和销毁destroy-method方法.这里怎么办呢? 我们可以使用注解的方式来指定初始化方法和销毁方法
PersonServiceBean.java
Java代码
package cn.itcast.service.impl; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.stereotype.Service; import cn.itcast.dao.PersonDao; import cn.itcast.service.PersonService; @Service("personService") //当Spring扫描到这个类之后就知道它要把这个类纳入到Spring容器中管理,而且它是作为服务层组件的 //可以通过personService这个名称获取这个bean了 public class PersonServiceBean implements PersonService { private PersonDao personDao; @PostConstruct //大家注意,这个注解不是Spring的 //以后学习EJB3的时候就可以发现,这个注解也是EJB3里面用来初始化bean的注解。 //这个注解用的范围很广泛,Spring对这个注解也做了支持 //这个注解的工作呢,后面也有个处理器对它进行解析,这个处理器在哪里注册呢? public void init(){ System.out.println("初始化"); } @PreDestroy //在bean实例被摧毁之前,会执行这个方法 public void destory(){ System.out.println("关闭资源"); } public void setPersonDao(PersonDao personDao) { this.personDao = personDao; } public void save(){ personDao.add(); } }
beans.xml
Xml代码
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:component-scan base-package="cn.itcast"/> <!-- 这个配置在背后注册了很多处理器,这些处理器都会对一些注解进行解析,其中就包括我们原先采用的 <context:annotation-config></context:annotation-config>这个配置项里面的注解里面使用的处理器 就是说使用了<context:component-scan>配置的话,<context:annotation-config>配置就可以去掉 --> </beans>
SpringTest.java
Java代码
package junit.test; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import cn.itcast.service.PersonService; public class SpringTest { @BeforeClass public static void setUpBeforeClass() throws Exception { } @Test public void instanceSpring() { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); PersonService personService = (PersonService) ctx.getBean("personService"); // 关于bean的名称,这里有条默认的规则,就是类的名称,然后第一个字母小写 ctx.close(); } }
运行单元测试代码,输出
初始化
关闭资源
这里已经给大家介绍完了怎样采用扫描的方式来把组件交给Spring管理,这种方式是我们目前在新开发应用中大量使用的方式,以前的应用中这种方式是没有这种功能的,以前采用Spring2.0是没有这种功能的,这个功能是2.5推出的,这个功能一推出,确实是被很多的新开发的项目所采用,因为这种方式确实是太方便了,能够大大提高我们的开发效率
相关文章推荐
- Spring、Spring自动扫描和管理Bean
- Spring自动扫描和管理bean bug1
- Spring自动扫描和管理bean
- spring学习笔记4--让sping自动扫描和管理Bean
- (7) 让Spring自动扫描和管理Bean ---- 通过在classpath自动扫描方式把组件纳入spring容器中管理
- Spring、Spring自动扫描和管理Bean
- 引用 Spring学习笔记(让Spring自动扫描和管理Bean)
- spring自动扫描和管理bean
- spring_让 spring自动扫描和管理bean
- 第四章 Spring进阶-自动扫描和管理Bean
- Spring(九)让Spring自动扫描和管理Bean
- [置顶] Spring自动扫描和管理Bean
- Spring、Spring自动扫描和管理Bean
- Spring自动扫描和管理Bean
- Spring2.5学习3.4_让Spring自动扫描和管理Bean
- (转)让Spring自动扫描和管理Bean
- JavaEE_SSH_Spring学习笔记(9)----让Spring自动扫描和管理Bean
- 让spring自动扫描管理bean
- ITCAST视频-Spring学习笔记(让Spring自动扫描和管理Bean)
- 让Spring自动扫描和管理Bean