http://blog.csdn.net/yerenyuan_pku/article/details/52861403

前面的例子我们都是使用XML的bean定义来配置组件。在一个稍大的项目中,通常会有上百个组件,如果这些组件采用XML的bean定义来配置,显然会增加配置文件的体积,查找及维护起来也不太方便。Spring2.5为我们引入了组件自动扫描机制,它可以在类路径底下寻找标注了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入进Spring容器中管理。它的作用和在XML文件中使用bean节点配置组件是一样的。要使用自动扫描机制,我们需要打开以下配置信息:

<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:component-scan base-package="cn.itcast" /> </beans>
  • 1
  • 2

其中<context:component-scan base-package="cn.itcast" />这个配置隐式注册了多个对注解进行解析处理的处理器,包括<context:annotation-config/>该配置注册的处理器,也就是说写了<context:component-scan base-package="cn.itcast" />配置,就不用写<context:annotation-config/>配置了,此外base-package为需要扫描的包(含子包)。 
@Service用于标注业务层组件、 @Controller用于标注控制层组件(如Struts2中的action)、@Repository用于标注数据访问组件,即DAO组件。而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。 
本文是建立在@Autowire注解与自动装配的案例基础上的。我们首先将Spring的配置文件改为:

<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd"> <context:component-scan base-package="cn.itcast" /> </beans>
  • 1

然后使用@Service注解标注PersonServiceBean类,如下:

@Service
public class PersonServiceBean implements PersonService {
private PersonDao personDao; public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
} @Override
public void save() {
personDao.add();
}
}
  • 1

使用@Repository注解标注PersonDaoBean类,如下:

@Repository
public class PersonDaoBean implements PersonDao {
@Override
public void add() {
System.out.println("执行PersonDaoBean中的add()方法");
}
}
  • 1

最后,我们修改SpringTest类的代码为:

public class SpringTest {

    @Test
public void instanceSpring() {
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personServiceBean");
PersonDao personDao = (PersonDao) ctx.getBean("personDaoBean");
System.out.println(personService);
System.out.println(personDao);
ctx.close();
} }
  • 1

测试instanceSpring()方法,可看到Eclipse控制台打印: 

如果我们想使用按指定名称获取,可将PersonServiceBean类的代码修改为:

@Service("personService")
public class PersonServiceBean implements PersonService {
private PersonDao personDao; public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
} @Override
public void save() {
personDao.add();
}
}
  • 1

这样,SpringTest类的代码应改为:

public class SpringTest {

    @Test
public void instanceSpring() {
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService");
System.out.println(personService);
ctx.close();
} }
  • 1
  • 2

测试instanceSpring()方法,可看到Eclipse控制台打印: 

我们前面学过Spring管理的bean的作用域,我们就能知道以上Spring管理的两个bean的作用域默认是singleton。当然了,我们也可以更改Spring管理的bean的作用域,如将PersonServiceBean类的代码改为:

@Service("personService") @Scope("prototype")
public class PersonServiceBean implements PersonService {
private PersonDao personDao; public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
} @Override
public void save() {
personDao.add();
}
}
  • 1

意味着Spring管理的PersonServiceBean这个bean的作用域变成prototype了,这时我们将SpringTest类的代码修改为:

public class SpringTest {

    @Test
public void instanceSpring() {
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService1 = (PersonService) ctx.getBean("personService");
PersonService personService2 = (PersonService) ctx.getBean("personService");
System.out.println(personService1 == personService2);
ctx.close();
} }
  • 1

测试instanceSpring()方法,可看到Eclipse控制台打印: 

prototype作用域本来就意味着每次从Spring容器获取bean都是新的对象嘛。

若是通过在classpath路径下自动扫描方这种式把组件纳入Spring容器中管理,如何指定bean的初始化方法和销毁方法呢?这时我们就需要用到两个注解:@PostConstruct和@PreDestroy。为了试验,我们将PersonServiceBean类的代码修改为:

@Service("personService")
public class PersonServiceBean implements PersonService {
private PersonDao personDao; @PostConstruct
public void init() {
System.out.println("初始化资源");
} @PreDestroy
public void destroy() {
System.out.println("销毁、关闭资源");
} public void setPersonDao(PersonDao personDao) {
this.personDao = personDao;
} @Override
public void save() {
personDao.add();
}
}
  • 1

接下来还要将SpringTest类的代码修改为:

public class SpringTest {

    @Test
public void instanceSpring() {
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
PersonService personService = (PersonService) ctx.getBean("personService");
ctx.close();
} }
  • 1

这样,测试instanceSpring()方法,Eclipse控制台会打印: 

如要查看源码,可点击让Spring自动扫描和管理Bean进行下载。

 
 

(转)让Spring自动扫描和管理Bean的更多相关文章

  1. Spring、Spring自动扫描和管理Bean

    Spring2.5为我们引入了组件自动扫描机制,它可以在类路径下寻找标记了@Component.@Service.@Controller.@Repository注解的类,并把这些类纳入到spring容 ...

  2. Spring第八发—自动装配及让Spring自动扫描和管理Bean

    依赖注入–自动装配依赖对象(了解即可) 对于自动装配,大家了解一下就可以了,实在不推荐大家使用.例子: byName:按名称装配,可以根据属性的名称,在容器中寻找跟该属性名相同的bean,如果没有找到 ...

  3. Spring是如何管理Bean

    容器是什么?spring中是如何体现的?一直有疑惑,这两天看了一下Spring管理bean的Demo,对于Spring中的容器有了简单的认识. 我们知道,容器是一个空间的概念,一般理解为可盛放物体的地 ...

  4. 使用Spring和SpringMVC管理bean时要注意的一个小细节

    最近一直在做毕业设计...用到了Shiro和SpringMVC..用过shiro的朋友都知道shiro需要自己去写Realm,然后把Realm注入到SecurityManager中.而Security ...

  5. Spring中管理Bean以及解析XML

    Spring是分层的轻量级框架 以IoC(Inverse of Control 反转控制)和AOP(Aspect Oriented Programming 面向切面编程)为核心 应用Spring的好处 ...

  6. 采用Spring管理Bean和依赖注入

    1. 实例化spring容器和从容器获取Bean对象 实例化Spring容器常用的两种方式: 方法一: 在类路径下寻找配置文件来实例化容器 [推荐使用] ApplicationContext ctx ...

  7. Spring的依赖注入和管理Bean

    采用Spring管理Bean和依赖注入 1.实例化spring容器 和 从容器获取Bean对象 实例化Spring容器常用的两种方式: 方法一: 在类路径下寻找配置文件来实例化容器 [推荐使用] Ap ...

  8. Spring的自动扫描与管理

    通过在classpath自动扫描方式把组件纳入spring容器中管理 前面的例子我们都是使用XML的bean定义来配置组件.在一个稍大的项目中,通常会有上百个组件,如果这些这组件采用xml的bean定 ...

  9. 通过在classpath自动扫描方式把组件纳入spring容器中管理。

    前面的例子我们都是使用xml的bean定义来配置组件,如果组件过多很臃肿.spring2.5引入了组件自动扫描机制,在指定目录下查找标注了@Component.@Service.@Controller ...

随机推荐

  1. Educational Codeforces Round 23

    A题 分析:注意两个点之间的倍数差,若为偶数则为YES,否则为NO #include "iostream" #include "cstdio" #include ...

  2. 如何生成Android的keystore文件

    步骤   1 找到本机电脑上jdk安装的目录,使用cmd命令打开命令窗口,输入cd  jdk目录(替换成你的jdk的bin目录),进入到jdk的bin目录,接下来你才可以使用jdk的命令进行操作 步骤 ...

  3. python: 使用matplotlib的pyplot绘制图表

    工作中需要观察数据的变化趋势,用python写了一段小程序来用显示简单图表,分享出来方便有同样需求的人,matplotlib是个很不错的库. #!encode=utf8 from matplotlib ...

  4. 洛谷 - P2293 - 高精度开根 - 高精度

    https://www.luogu.org/problemnew/show/P2293 要求求出给定高精度整数的非负根取整的结果. 还有神仙用Python的浮点pow运算骗到不少分的. 唉! 那么我们 ...

  5. bzoj 2946: [Poi2000]公共串【SAM】

    对第一个串建SAM,把剩下的串在上面跑,每次跑一个串的时候在SAM的端点上记录匹配到这的最大长度,然后对这些串跑的结果取min,然后从这些节点的min中取max就是答案 注意在一个点更新后它的祖先也会 ...

  6. 第八篇 .NET高级技术之字符串暂存池(缓冲池)

    字符串不可变性,字符串的‘暂存池’两个特性 字符串是引用类型,程序中会存在大量的字符串对象,如果每次都创建一个字符串对象,会比较浪费内存.性能低,因此CLR做了“暂存池”(拘留池,缓冲池,暂存池),在 ...

  7. springboot&mybatis 增删改查系列(二)

    数据库篇 我的数据库名为data0525,数据表名为user,其中有五列uid,uname,upass,usex,umessage.uid为主键并且自动生成,由于是练习表,所以并没有考虑设计的合理性. ...

  8. Python基础知识(1)

    Python 3 1:print:输出信息    例子:   ( 所有的标点符号都要是英文状态下输入,要不然会报错) print(“hello world”) 2:注意 : python 和 pyth ...

  9. Codeforces Round #402 (Div. 2) B

    Description Polycarp is crazy about round numbers. He especially likes the numbers divisible by 10k. ...

  10. Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) B

    Description Bear Limak examines a social network. Its main functionality is that two members can bec ...