IOC容器装配Beanxml方式.docx
- 文档编号:3185645
- 上传时间:2023-05-05
- 格式:DOCX
- 页数:21
- 大小:108.51KB
IOC容器装配Beanxml方式.docx
《IOC容器装配Beanxml方式.docx》由会员分享,可在线阅读,更多相关《IOC容器装配Beanxml方式.docx(21页珍藏版)》请在冰点文库上搜索。
IOC容器装配Beanxml方式
IOC容器装配Bean(xml方式)
1.Spring 提供配置Bean三种实例化方式
1)使用类构造器实例化(默认无参数)
1.
2)使用静态工厂方法实例化(简单工厂模式)
1.//下面这段配置的含义:
调用Bean2Factory的getBean2方法得到bean2
2.
3)使用实例工厂方法实例化(工厂方法模式)
1.//先创建工厂实例bean3Facory,再通过工厂实例创建目标bean实例
2.
3.
2.Bean的其它属性配置
早期Spring开发中Bean的 id属性 ,遵守xml语法id约束
* id 的命名要满足XML对ID属性命名规范 必须以字母开始,可以使用字母、数字、连字符、下划线、句话、冒号。
*使用name属性,就可以使用很多特殊字符,早期在struts1和spring整合,如
**如果元素没有id只有name ,name 属性值可以作为id 使用
1.* scope="singleton" 单例 ,在Spring IoC容器中仅存在一个Bean实例 (默认的scope)
2.* scope="prototype" 多例 ,每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时 ,相当于执行new XxxBean()
3.* scope="request" 用于web开发,将Bean放入request范围 ,request.setAttribute("xxx") , 在同一个request 获得同一个Bean
4.* scope="session" 用于web开发,将Bean 放入Session范围,在同一个Session 获得同一个Bean
5.* scope="globalSession" 一般用于Porlet应用环境 , 分布式系统存在全局session概念 ,如果不是porlet环境,globalSession 等同于Session
在开发中主要使用 scope="singleton"、 scope="prototype"
如果在applicationContext.cfg.xml配置文件中的bean,未指定scope属性,那么默认为singleton
3.Bean的生命周期
1)在配置
1.
在JavaBean中书写在,
1.packagecn.itcast.spring.d_lifecycle;
2.publicclassLifeCycleBean{
3.publicvoidsetup(){
4.System.out.println("初始化...");
5.}
6.
7.publicvoidteardown(){
8.System.out.println("销毁....");
9.}
10.
11.}
进行测试:
1.@Test
2.//测试Spring生命周期
3.publicvoiddemo(){
4. ClassPathXmlApplicationContextapplicationContext=newClassPathXmlApplicationContext("applicationContext.xml");
5. LifeCycleBeanlifeCycleBean=(LifeCycleBean)applicationContext.getBean("lifeCycleBean");
6. System.out.println(lifeCycleBean);
7.}
运行结果:
我们发现:
运行完程序,销毁方法没有执行。
解析:
这个程序运行了,但是Spring容器并不知道何时销毁。
举个例子:
例如把一个Spring容器交给tomcat管理时,tomcat停止时,他就会自动调用destroy方法。
那么我们就自己来调用这个方法:
applicationContext.close();
此时,就会调用销毁方法:
需要注意的问题:
* destroy-method 只对 scope="singleton" 有效
* 销毁方法,必须关闭ApplicationContext对象(手动调用),才会被调用
1.ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
2.applicationContext.close();
2)Bean的完整生命周期 (十一步骤)【了解内容,但是对于spring内部操作理解有一定帮助】
①instantiate bean对象实例化
②populate properties 封装属性
③如果Bean实现BeanNameAware 执行 setBeanName
④如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
⑤如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization,BeanPostProcessor接口提供钩子函数,用来动态扩展修改Bean。
(程序自动调用后处理Bean)
1.publicclassMyBeanPostProcessorimplementsBeanPostProcessor{
2.publicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)
3.throwsBeansException{
4.System.out.println("第八步:
后处理Bean,after初始化。
");
5.//后处理Bean,在这里加上一个动态代理,就把这个Bean给修改了。
6.returnbean;//返回bean,表示没有修改,如果使用动态代理,返回代理对象,那么就修改了。
7.}
8.publicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)
9.throwsBeansException{
10.System.out.println("第五步:
后处理Bean的:
before初始化!
!
");
11.//后处理Bean,在这里加上一个动态代理,就把这个Bean给修改了。
12.returnbean;//返回bean本身,表示没有修改。
13.}
14.}
15.注意:
这个前处理Bean和后处理Bean会对所有的Bean进行拦截。
⑥如果Bean实现InitializingBean 执行 afterPropertiesSet
⑦调用
⑧如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
⑨执行业务处理
⑩如果Bean实现 DisposableBean 执行 destroy
⑪调用
*为了能够比较清晰的看到上面的每一个步骤,我们模拟真实开发场景,定义一个接口和一个实现类
1.//用户数据库操作
2.publicinterfaceUserDAO{
3.publicvoidadd();
4.publicvoidsearch();
5.}
实现类:
1.//实现DAO方法
2.publicclassUserDAOImplimplementsUserDAO,BeanNameAware,ApplicationContextAware,InitializingBean,DisposableBean{
3.privateStringcompany;
4.
5.publicUserDAOImpl(){
6.System.out.println("第一步Bean的实例化...");
7.}
8.
9.//设置company
10.publicvoidsetCompany(Stringcompany){
11.System.out.println("第二步设置Bean的属性");
12.pany=company;
13.}
14.//如果实现了BeanNameAware接口,那么会将bean的那么设置到程序中,也就是userDao
15.publicvoidsetBeanName(StringbeanName){
16.System.out.println("第三步将xml配置Bean的name设置到程序中:
"+beanName);
17.//
18.}
19.
20.publicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException{
21.System.out.println("第四步将整合工厂上下文对象设置到Bean中");
22.}
23.
24.publicvoidafterPropertiesSet()throwsException{
25.System.out.println("第六步属性设置完成后...");
26.}
27.
28.publicvoidsetup(){
29.System.out.println("第七步配置初始化方法...init-method='setup'");
30.}
31.
32.//Bean初始化完毕,如果有业务方法,那么就开始执行,以下方法模拟业务方法。
33.
34.//这是在接口中定义的业务操作方法
35.publicvoidadd(){
36.System.out.println("第九步业务操作....添加");
37.}
38.//这是在接口中定义的业务操作方法
39.publicvoidsearch(){
40.System.out.println("第九步业务操作....查询");
41.}
42.
43.//destroy方法必须自己调用closed方法后才会执行。
44.publicvoiddestroy()throwsException{
45.// 这个destroy无需配置,实现这个接口,就会自动的去调用destroy方法。
46.System.out.println("第十步无需配置的销毁方法");
47.}
48.
49.publicvoidteardown(){
50.System.out.println("第十一步通过配置设置销毁方法...");
51.}
52.
53.}
其中少了第五步和第八步,此项内容在上面对应序号位置找。
配置文件applicationContext.cfg.xml:
1.
xmlversion="1.0"encoding="UTF-8"?
>
2.
--引入约束来自xsd-config.html文件-->
3. //www.springframework.org/schema/beans" 4.xmlns: p="http: //www.springframework.org/schema/p" 5.xmlns: xsi="http: //www.w3.org/2001/XMLSchema-instance" 6.xsi: schemaLocation=" 7.http: //www.springframework.org/schema/beanshttp: //www.springframework.org/schema/beans/spring-beans.xsd"> 8. 9. 10. --第二步,设置bean的属性--> 11. 12. 13. 14. --必须配置后处理Bean,bean没有id因为由Spring框架内部调用--> 15. 16. 17. 编写测试类: 1.@Test 2.//测试Spring生命周期 3.publicvoiddemo2(){ 4. ClassPathXmlApplicationContextapplicationContext=newClassPathXmlApplicationContext("applicationContext.xml"); 5. UserDAOuserDAO=(UserDAO)applicationContext.getBean("userDAO"); 6. 7.//执行业务方法 8. userDAO.add(); 9. userDAO.search(); 10. 11. //关闭工厂 12. applicationContext.close(); 13.} 运行结果: 分析: 前面前处理Bean和后处理Bean被执行多次,表示: 钩子函数会对每个bean进行拦截(前面已经配置了其他的几个Bean,每个Bean都执行2次à前处理Bean后处理bean)。 故而执行多次,反复连续的输出五,八。 第三步和第四步,使我们写的Bean了解Spring容器 第五步和第八步,使用BeanPostProcessor 就是钩子函数,作用用来对Bean对象进行扩展。 问题: 在userDAO对象所有方法上 添加运行时间监控 【用后处理bean对目标bean在构造时进行代理,对原有方法进行扩展增强! 】 我们可以利用后处理bean(BeanPostProcessor)与动态代理一起完成此功能,我们只需要在后处理bean的postProcessAfterInitialization方法里面改动代码即可 1./** 2.*bean就是对象实例beanName就是xml配置Bean的id或者name 3.*/ 4.publicObjectpostProcessAfterInitialization(finalObjectbean,StringbeanName)throwsBeansException{ 5. System.out.println("第八步执行后处理Bean的初始化完成后方法..."); 6.if(beanName.equals("userDAO")){ 7. //需要进行时间监控Bean 8.Objectproxy=Proxy.newProxyInstance(bean.getClass().getClassLoader(),bean.getClass().getInterfaces(),newInvocationHandler(){ 9. publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{ 10. if(method.getName().equals("search")){ 11. //增强search方法 12.System.out.println("开始时间: "+System.currentTimeMillis()); 13.Objectresult=method.invoke(bean,args); 14.System.out.println("结束时间: "+System.currentTimeMillis()); 15.returnresult; 16.}else{ 17.//不加强 18.returnmethod.invoke(bean,args); 19.} 20.} 21.}); 22.returnproxy; 23. } 24.returnbean; 25.} 运行测试结果: 我们发现: 在业务方法search的前后环绕了增强的功能! ========================================================================================================================== 4.Spring的Bean属性的依赖注入 *spring支持构造器注入和setter方法注入 第一种 构造器注入,通过 1./** 2.*轿车(构造函数注入属性) 3.*/ 4.publicclassCar{ 5.privateStringname; 6.privatedoubleprice; 7. 8.publicCar(Stringname,doubleprice){ 9.super(); 10.this.name=name; 11.this.price=price; 12.} 13. 14.@Override 15.publicStringtoString(){ 16.return"Car[name="+name+",price="+price+"]"; 17.} 18. 19.} 配置文件: 1. --构造器注入--> 2. 3. --通过构造器参数,完成属性注入--> 4. --第一个参数String类型参数--> 5. 6. 第二种 setter方法注入, 通过 1./** 2.*通过setter方法完成属性注入 3.*/ 4.publicclassCar2{ 5.privateStringname; 6.privatedoubleprice; 7. 8.//注入属性时只需要提供set方法 9.publicvoidsetName(Stringname){ 10.this.name=name; 11.} 12. 13.publicvoidsetPrice(doubleprice){ 14.this.price=price; 15.} 16. 17.@Override 18.publicStringtoString(){ 19.return"Car2[name="+name+",price="+price+"]"; 20.} 21. 22.} 配置文件: 1. --setter方法注入--> 2. 3. --通过property元素完成属性注入--> 4.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- IOC 容器 装配 Beanxml 方式