详解spring自动扫描包
配置文件
前面的例子我们都是使用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>
其中<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>
一个实例
然后使用@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(); } }
使用@Repository注解标注PersonDaoBean类,如下:
@Repository public class PersonDaoBean implements PersonDao { @Override public void add() { System.out.println("执行PersonDaoBean中的add()方法"); } }
最后,我们修改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(); } }
测试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(); } }
这样,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(); } }
测试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(); } }
意味着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(); } }
测试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(); } }
接下来还要将SpringTest类的代码修改为:
public class SpringTest { @Test public void instanceSpring() { AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); PersonService personService = (PersonService) ctx.getBean("personService"); ctx.close(); } }
这样,测试instanceSpring()方法,Eclipse控制台会打印:
如要查看源码,可点击让Spring自动扫描和管理Bean进行下载。
总结
以上所述是小编给大家介绍的spring自动扫描包,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
- HDU 1002 A + B Problem II(高精度加法(C++/Java))
- POJ 1018 Communication System
- POJ 1017 Packets
- Codeforces 725B Food on the Plane
- Codefoces 723B Text Document Analysis
- Codefoces 723A The New Year: Meeting Friends
- ECJTUACM16 Winter vacation training #1 题解&源码
- 信息学奥赛一本通算法(C++版)基础算法:高精度计算
- 看破欧拉函数的奥秘
- 线段树入门总结
- 从零基础学三分查找
- Codeforces Beta Round #1 A,B,C
- 线性分类器-中篇
- isupper()函数
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 使用Pyppeteer进行gmail模拟登录
- 一个没法商用,但是好玩有趣的 Python 手绘图形库!
- 使用豆瓣源安装python包
- [已解决]报错:ValueError: Expected 2D array, got scalar array instead
- [已解决]报错UnicodeDecodeError
- [已解决]报错Could not install packages due to an EnvironmentError
- 用Cython加速Python代码
- [已解决]windows安装docker的问题
- 使用VBA达到vlookup效果
- Excel简单应用
- Pandas异常值处理
- Pandas重复值处理
- Pandas缺失值处理
- Pandas分类数据和顺序数据转换为标志变量
- 使用ProxyBroker构建代理池