spring_bean三种装配方式
bean装配:spring ioc 容器将bean对象创建好并传递给使用者的过程叫bean的装配
spring ioc 会创建我们在配置文件中配置好的对象,并将对象返回给使用者,spring ioc创建对象的方式有以下三种
1:默认方式,通过构造器来创建
<bean id="自定义id" class="接口的实现类" />2:实例工厂
<bean id="factory" class="工厂类" /> <bean id="自定义id" factory-bean="factory" factory-method="调用的实例化工厂方法" />3:静态工厂
<bean id="自定义id" class="工厂类" factory-method="静态工厂方法" /># 默认方式
该方式spring ioc容器会调用bean(接口实现类)的无参构造方法来创建对象,当创建一个java类后,系统会自动在类中创默认构造函数,当自己创建个构造方法时默认构造函数就会不存在,所以开发者需确保在bean中存在无参构造方法
<!-- 默认方式 --> <bean id="studentService" class="com.doaoao.impl.StudentServiceImpl"/># 实例工厂
1:定义一个工厂类,该类中的方法都是非静态的(方法的返回值为StudentService类型)
package com.doaoao.factory; import com.doaoao.impl.StudentServiceImpl; import com.doaoao.service.StudentService; public class BeanFactory {public StudentService createStudentService(){return new StudentServiceImpl();} }2:修改配置文件中的内容(主要为了告诉spirng我们要使用 实例工厂 方法)
<!-- 创建实例工厂配置温江 id 和class --> <bean id="myFactory" class="com.doaoao.factory.BeanFactory" /><!-- 将上创建的实例工厂 myFactory添加进去,利用实例工厂中的方法 factory-method指定的方法,来创建studentService --> <bean id="studentService" factory-bean="myFactory" factory-method="createStudentService" />其它与之前的相同
# 静态工厂(中的方法都是 static 修饰的)
1:定义一个工厂类,类的中的方法都为静态方法(从该类中来看和实例工厂对比只是多了一个static)
package com.doaoao.factory; import com.doaoao.impl.StudentServiceImpl; import com.doaoao.service.StudentService; public class StaticBeanFactory {public static StudentService createStudentService(){return new StudentServiceImpl();} }2:修改配置文件中的内容
<!-- 静态工厂:调用class指定的工厂类的方法 createStudentService 来创建 id 指定的对象--> <bean id="studentService" class="com.doaoao.factory.StaticBeanFactory" factory-method="createStudentService" />## 注:在使用时,一般使用默认方式即可
## bean的作用域
singleton: 单例模式。即在一个Spring ioc容器中,只创建一个对象,默认为单例模式
prototype: 原型模式。即每次使用 getBean 方法获取的同一个bean的实例都是一个新的实例
request:对于每次 HTTP 请求,都将会产生一个不同的 Bean 实例
session:对于每个不同的 HTTP session,都将产生一个不同的 Bean 实例(同一个浏览器中产生同一个session)
application:在一个web应用中会产生一个bean实例,就相当于在一个ServletContext中只有该bean的实例
websocket:在一个websocket中会产生一个bean实例
单利模式例子:
1:在StudetnServiceImpl.java中创建一个无参构造方法
package com.doaoao.impl; import com.doaoao.service.StudentService; public class StudentServiceImpl implements StudentService {@Overridepublic void testDao() {System.out.println("Hello World");}public StudentServiceImpl(){System.out.println("执行 StudentService的构造方法");} }2:在测试类中创建两个对象,分别执行两个对象,看输出
@Testpublic void sprintTest(){// 读取spring配置文件ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 从配置文件中获取对应id所对应的对象StudentService studentService = (StudentService) context.getBean("studentService");StudentService studentService1 = (StudentService) context.getBean("studentService"); System.out.println(studentService);System.out.println(studentService1);}3:输出结果分析:只执行了一次bean中的构造方法,因为在创建对象时会执行构造方法,说明单利模式只创建了一次构造方法
执行 StudentService的构造方法 com.doaoao.impl.StudentServiceImpl@64cd705f com.doaoao.impl.StudentServiceImpl@64cd705f## 在配置文件中将作用域修改为singleton(单例模式)
<bean id="studentService" class="com.doaoao.impl.StudentServiceImpl" scope="singleton"/># 输出结果和上方默认方式相同 执行 StudentService的构造方法 com.doaoao.impl.StudentServiceImpl@418e7838 com.doaoao.impl.StudentServiceImpl@418e7838## 在配置文件中将作用域修改为 prototype(原型模式)每次使用getBean时都会创建
<bean id="studentService" class="com.doaoao.impl.StudentServiceImpl" scope="prototype"/># 输出 <!-- 执行两次构造方法 --> 执行 StudentService的构造方法 执行 StudentService的构造方法 com.doaoao.impl.StudentServiceImpl@5ae50ce6 com.doaoao.impl.StudentServiceImpl@6f96c77
## BeanPostProcessor 接口
实现该接口的类称为bean后处理器,在该类中重写两个方法"postProcessBeforeInitialization" 和 "postProcessAfterInitialization",在获得某个bean的对象后,在该对象的执行之前和执行之后分别调用上面两个方法,我们可以通过这两个方法实现特定的功能
以下下为实例:
package com.doaoao.processor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;public class BeanPostProcessorTest implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("执行postProcessBeforeInitialization");// 注意:这里不能返回null,必须返回beanreturn bean;}@Overridepublic Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {if("studentService".equals(beanName)){//创建InvocationHandler invocationHandler = ((Object p,Method method,Object[] args)->{// 调用study方法时,使用动态代理对其进行增强if("study".equals(method.getName())) {System.out.println("目标方法开始执行");// 执行目标方法Object result = method.invoke(bean, args);System.out.println("目标方法结束执行");return result;}return method.invoke(bean,args);});// 增强beanObject proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(),bean.getClass().getInterfaces(),invocationHandler);System.out.println("postProcessAfterInitialization执行");return proxy;}return bean;} }
## bean的生命周期
可以指定bean在初始化和销毁时执行特定的方法
1:在StudentServiceImpl类中创建两个方法 init 和 destroy
package com.doaoao.impl; import com.doaoao.service.StudentService; public class StudentServiceImpl implements StudentService {@Overridepublic void testDao() {System.out.println("Hello World");}public StudentServiceImpl(){System.out.println("执行 StudentService的构造方法");}public void init(){System.out.println("执行初始化方法");}public void destroy(){System.out.println("执行销毁方法");} }2:在配置文件中添加两个属性 init-method 和 destroy-method 分别指定初始化方法和销毁方法
<bean id="studentService" class="com.doaoao.impl.StudentServiceImpl" init-method="init" destroy-method="destroy"/>3:修改测试类中的内容
@Testpublic void sprintTest(){// 读取spring配置文件ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 从配置文件中获取对应id所对应的对象StudentService studentService = (StudentService) context.getBean("studentService");// 调用对象中的指定方法 studentService.testDao();// 将context给关闭 ((ClassPathXmlApplicationContext) context).close();}4:查看输出(当创建时执行的方法,当销毁时执行的方法)
执行 StudentService的构造方法 执行初始化方法 Hello World 执行销毁方法...
本笔记参考自:小猴子老师教程 http://www.monkey1024.com
转载于:https://www.cnblogs.com/Doaoao/p/10741333.html
spring_bean三种装配方式相关推荐
- spring bean作用域_Srping中Bean的三种装配方式:大魏Java记10
一.Bean的作用域 Spring在初始化一个Bean实例时,可以同时为其指定特定的作用域.作用域将会对Bean的生命周期和创建方式产生影响. Bean的作用域类型: Singleton作用域是Spr ...
- spring入门之Spring 常用的三种注入方式
Spring 常用的三种注入方式 Spring 通过 DI(依赖注入)实现 IOC(控制反转),常用的注入方式主要有三种:构造方法注入,set 方法注入,基于注解的注入. 一.通过构造方法注入 先简单 ...
- Spring的三种注入方式(为什么推荐构造器注入?)
Spring的三种注入方式 一.属性注入 @Resource和@Autowired的区别 为什么尽量使用 @Resource? 二.setter 注入 三.构造器注入 具体可以看看Spring官网 为 ...
- Spring学习之Spring三种装配机制:(一)自动化装配bean
装配:创建应用组件(对象)之间的协作的行为,这也是Spring依赖注入(DI)的本质. Spring提供了三种装配机制: 隐式的自动装配bean: 通过java代码装配bean(显示): 通XML中装 ...
- Hive metastore三种配置方式
Hive的meta数据支持以下三种存储方式,其中两种属于本地存储,一种为远端存储.远端存储比较适合生产环境.Hive官方wiki详细介绍了这三种方式,链接为:Hive Metastore. 一.本地d ...
- python数据结构与算法:二叉树及三种遍历方式(先序遍历/中序遍历/后序遍历)
树的实现采用queue的形式: 树的三种遍历方式(广度优先白能力法):先序遍历(根左右),中序遍历(左根右)以及后序遍历(左右根) ######################P6.4 数据结构### ...
- FPGA之道(41)HDL的三种描述方式
文章目录 前言 三种描述方式 结构化描述方式 数据流描述方式 行为级描述方式 前言 常编写Verilog代码的就会知道,我们对于某一功能的描述,可以通过门电路来描述,也可以直接描述其功能等,这就牵扯到 ...
- 【 Verilog HDL 】HDL的三种描述方式
当我们使用HDL代码描述硬件功能的时候,主要有三种基本描述方式,即结构化描述方式.数据流描述方式和行为级描述方式.通过本次总结,我们将明白到底我们描述的电路是什么方式描述的. 结构化描述方式 结构化描 ...
- oracle if=,oracle中if/else的三种实现方式详解
1.标准sql规范 1.单个IF IF v=... THEN END IF; 2.IF ... ELSE IF v=... THEN ELSE t....; END IF; 3.多个IF IF v=. ...
最新文章
- Unity Android 2021:用C#打造3D ZigZag赛车游戏
- 抛出一个nullpointerexception_Java 14 发布了,再也不怕 NullPointerException 了!
- 空气培养皿采样后保存_环境监测基础知识——环境空气监测技术之布点采样
- php chr() ord()中文截取乱码问题解决方法
- oracle文字与格式字符串不匹配的解决
- Java线程--扩展
- oracle 中update select 和连接字符串配合使用
- 末日博士:比特币不应出现在散户或机构投资者的投资组合中
- python3.7适用的opencv_通过python3.7.3使用openCV截图一个区域
- 在Hyper-V主机中支持VLAN
- iOS应用不同状态下收到推送的处理
- SWIFT显示底部的工具条
- Luogu3942 将军令
- 港台服冒险岛枫之谷传统登录方式密码解密及自动登录方式
- 一文详解高精地图构建与SLAM感知优化建图策略
- 新浪微博产品分析报告
- 八数码问题引发的思考
- 大幅面遥感影像多尺度分割与尺度转换-初探
- thinker board s debian系统安装配置
- 真香啊,一文讲透金融风控建模全流程(Python)