bean创建相关
bean 创建顺序
1. 在 spring 的 ioc 容器, 默认是按照配置的顺序创建 bean 对象
<bean id="student01" class="com.hspedu.bean.Student" />
<bean id="department01" class="com.hspedu.bean.Department" />
会先创建 student01 这个 bean 对象,然后创建 department01 这个 bean 对象
2. 如果这样配置
<bean id="student01" class="com.hspedu.bean.Student" depends-on="department01"/>
<bean id="department01" class="com.hspedu.bean.Department" />
会先创建 department01 对象,再创建 student01 对象
<!--bean对象的加载顺序——默认情况下是按照写的顺序,如果有depend的话就先加载depend的的--> <bean class="com.recorder.spring.bean.Student" id="student" depends-on="class"/> <bean class="com.recorder.spring.bean.Class" id="class"/>
ioc容器会先将各个bean创建好。之后再创建各个bean之间的引用关系
bean 对象的单例和多例
在 spring 的 ioc 容器, 在默认是按照单例创建的,即配置一个 bean 对象后,ioc 容器只会创建一个 bean 实例。
如果希望 ioc 容器配置的某个 bean 对象,是以多个实例形式创建的则可以通过配置scope="prototype" 来指定
<!--bean对象的单例和多例 在spring的ioc容器,bean对象默认是按照单例创建的,即配置一个bean对象后,ioc容器只会创建一个bean实例(scope默认是singleton)。 如果,我们希望ioc容器配置的某个bean对象,是以多个实例形式创建的则可以通过配置scope="prototype" 来指定--> <!--1. 默认是单例 singleton, 在启动容器时, 默认就会创建 , 并放入到 singletonObjects 集合--> <!--2. 当 <bean scope="prototype" > 设置为多实例机制后, 该 bean 是在 getBean()时才创 建--> <!--3. 如 果 是 单 例 singleton, 同 时 希 望 在 getBean 时 才 创 建 , 可 以 指 定 懒 加 载 lazy-init="true" (注意默认是 false)--> <!--4. 通常情况下, lazy-init 就使用默认值 false , 在开发看来, 用空间换时间是值得的, 除非 有特殊的要求.--> <!--5. 如果 scope="prototype" 这时你的 lazy-init 属性的值不管是 ture, 还是 false 都是在 getBean 时候,才创建对象.--> <bean class="com.recorder.spring.bean.Cat" id="cat01" scope="prototype"> <property name="id" value="1"></property> <property name="name" value="咪咪"></property> </bean>
可以看到三只cat并不是同一个对象


bean 的生命周期
说明: bean 对象创建是由 JVM 完成的,然后执行如下方法
1. 执行构造器
2. 执行 set 相关方法
3. 调用 bean 的初始化的方法(需要配置)
4. 使用 bean
5. 当容器关闭时候,调用 bean 的销毁方法(需要配置)
演示:
public class House { private String name; public House() { //System.out.println("House() 构造器..."); } public String getName() { return name; } public void setName(String name) { //System.out.println("House setName()=" + name); this.name = name; } //解读: //1. 这个方法(名字)是程序员来编写的. //2. 根据自己的业务逻辑来写. public void init() { //System.out.println("House init().."); } //解读: //1. 这个方法是程序员来编写的. //2. 根据自己的业务逻辑来写. //3. 名字也不是固定的 public void destroy() { System.out.println("House destroy().."); } @Override public String toString() { return "House{" + "name='" + name + '\'' + '}'; } }
xml配置
<!--bean对象的生命周期--> <bean class="com.recorder.spring.bean.House" id="house" init-method="init" destroy-method="destroy"> <property name="name" value="四合院"></property> </bean>
测试
@Test //bean对象的生命周期 public void lifeCircleOfBean() { //创建一个容器,并和配置文件关联(一个容器关联一个配置文件) ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml"); House house = ioc.getBean("house", House.class); System.out.println("using house" + house); ((ConfigurableApplicationContext) ioc).close();//销毁容器 //输出内容: // House() 构造器... //House setName()=四合院 //House init().. //using houseHouse{name='四合院'} //House destroy().. }
使用细节:
1. 初始化 init 方法和 destory 方法, 是程序员来指定
2. 销毁方法就是当关闭容器时,才会被调用
配置 bean 的后置处理器
● 说明:
1. 在 spring 的 ioc 容器,可以配置 bean 的后置处理器
2. 该处理器/对象会在 bean 初始化方法调用前和初始化方法调用后被调用
3. 程序员可以在后置处理器中编写自己的代码
● 应用实例演示
创建一个后置处理器
package com.recorder.spring.bean; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * @author 紫英 * @version 1.0 * @discription 后置处理器 需要实现 BeanPostProcessor接口 */ public class MyBeanPostProcessor implements BeanPostProcessor { /** * 调用时机: 在Bean的init方法前被调用 * @param bean 传入的在IOC容器中创建/配置的Bean * @param beanName 传入的在IOC容器中创建/配置的Bean的id * @return 程序员对传入的bean 进行修改/处理【如果有需要的话】,之后将其返回 * @throws BeansException 异常 */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("bean= " + beanName + " beanName= " + beanName); //将所有house类型的名字都转换为汤臣一品 if (bean instanceof House){ ((House)bean).setName("汤臣一品"); } return bean; } /** * 调用时机: 在Bean的init方法后被调用 * @param bean 传入的在IOC容器中创建/配置的Bean * @param beanName 传入的在IOC容器中创建/配置的Bean的id * @return 程序员对传入的bean 进行修改/处理【如果有需要的话】,之后将其返回 * @throws BeansException 异常 */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("bean= " + beanName + " beanName= " + beanName); return bean; } }
配置xml
<!--配置house信息--> <bean class="com.recorder.spring.bean.House" id="house01" init-method="init" destroy-method="destroy" > <property name="name" value="大豪宅"/> </bean>
配置后置处理器
<!--配置后置处理器对象 解读: 1. 当我们在beans02.xml 容器配置文件 配置了 MyBeanPostProcessor 2. 这时后置处理器对象,就会作用在该容器创建的(所有)Bean对象 3. 已经是针对所有对象编程->切面编程AOP --> <bean class="com.recorder.spring.bean.MyBeanPostProcessor" id="myBeanPostProcessor"/>
其它说明
1、怎么执行到这个方法?=> 使用 AOP(反射+动态代理+IO+容器+注解)
2、有什么用?=> 可以对 IOC 容器中所有的对象进行统一处理 ,比如 日志处理/权限的校验/安全的验证/事务管理.
-初步体验案例: 如果类型是 House 的统一改成 上海豪宅
3、针对容器的所有对象吗? 是的=>切面编程特点


通过属性文件给 bean 注入值
创建my.properties


xml配置
<!--通过属性文件给 bean 注入值--> <!--如果没有成功引入 将文件修改成All problem 然后提示错误 alt + enter--> <!--这里的属性通过${属性名}来赋值,属性名就是my.properties文件中的k--> <context:property-placeholder location="classpath:my.properties"/> <bean class="com.recorder.spring.bean.Hero" id="hero08"> <property name="id" value="${id}"/> <property name="name" value="${name}"/> <property name="skill" value="${skill}"/> </bean>

![]()
如果是中文需要手动转成Unicode编码,再放到my.properties中
本文来自博客园,作者:紫英626,转载请注明原文链接:https://www.cnblogs.com/recorderM/p/16804098.html

浙公网安备 33010602011771号