高端网站制作网站建设,咨询公司属于什么行业,wordpress美化文章内相册,asp.net做网站系统目录
1.Bean的初始化过程
1.1代码详解
1.2思考
2.Bean的单例与多例选择
2.1论证单例与多例优缺点
2.2论证初始化时间点
2.3个例演示 Spring Bean的生命周期#xff1a; 一、通过XML、Java annotation#xff08;注解#xff09;以及Java Configuration(配置类),等方式…目录
1.Bean的初始化过程
1.1代码详解
1.2思考
2.Bean的单例与多例选择
2.1论证单例与多例优缺点
2.2论证初始化时间点
2.3个例演示 Spring Bean的生命周期 一、通过XML、Java annotation注解以及Java Configuration(配置类),等方式加载Spring Bean 二、BeanDefinitionReader解析Bean的定义。在Spring容器启动过程中,会将Bean解析成Spring内部的BeanDefinition结构;理解为将spring.xml中的bean标签转换成BeanDefinition结构有点类似于XML解析 三、BeanDefinition包含了很多属性和方法。例如id、class类名、scope、ref依赖的bean等等。其实就是将bean例如bean的定义信息 存储到这个对应BeanDefinition相应的属性中 四、BeanFactoryPostProcessor是Spring容器功能的扩展接口。 注意 1BeanFactoryPostProcessor在spring容器加载完BeanDefinition之后 在bean实例化之前执行的 2对bean元数据BeanDefinition进行加工处理也就是BeanDefinition 属性填充、修改等操作 五、BeanFactorybean工厂。它按照我们的要求生产我们需要的各种各样的bean。 六、Aware感知接口在实际开发中经常需要用到Spring容器本身的功能资源 例如BeanNameAware、ApplicationContextAware等等 BeanDefinition 实现了 BeanNameAware、ApplicationContextAware 七、BeanPostProcessor后置处理器。在Bean对象实例化和引入注入完毕后 在显示调用初始化方法的前后添加自定义的逻辑。类似于AOP的绕环通知 前提条件如果检测到Bean对象实现了BeanPostProcessor后置处理器才会执行 Before和After方法 BeanPostProcessor 1Before 2调用初始化BeanInitializingBean和init-methodBean的初始化才算完成 3After 完成了Bean的创建工作 八、destory销毁 1.Bean的初始化过程 1.xml/annotation/configuation/配置JavaBean 2.BeanDefinitionReader解析配置的JavaBean得到Beandefinition最终得到ListBeanDefinition集合 3.触发BeanFactoryPostProcessor在JavaBean初始化之前执行 4.Spring中的BeanFactory会通过ListBeanDefinition集合遍历初始化所有的JavaBean对象 5.如果自己的JavaBean需要调动Spring上下文中的资源(方法或属性)那么需要实现*Aware感知接口 6.如果自己的JavaBean已经初始化好了还需扩展功能那么需要借助BeanPostProcessor后置处理器来实现 具体图解与流程图如下 1.1代码详解
BeanFactoryPostProcessor是Spring容器功能的扩展接口怎么理解比如假设我们现在有一个内部类Person其原本有三个属性。BeanFactoryPostProcessor的作用就是可以在初始化对象之前可以做一个补充它内部类原本只有三个属性我们可以给它加一个关联属性User进去并对新增的关联属性User对象做出相对应的处理具体代码详解如下
package com.kissship.beanlife;/*** author Kissship* site www.Kissship.com* company xxx公司* create 2023-08-18-14:17*/
public class Demo1 {public static void main(String[] args) {
// BeanDefinition}
}class User{
//无值
}
class Person{private int pid;private String name;private String sex;private User user;//扩展新增的关联属性(无值)public int getPid() {return pid;}public void setPid(int pid) {this.pid pid;}public String getName() {return name;}public void setName(String name) {this.name name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex sex;}public Person() {}//在初始化对象之前可以做一个补充比如上面原本只有三个属性我们也可以给它加一个关联属性Userpublic Person(int pid, String name, String sex) {this.init();//扩展的内容this.pid pid;this.name name;this.sex sex;}//这里可以针对我们新增的关联属性User对象作出处理public void init() {}
}
解析配置得到List集合与遍历初始化Bean对象具体代码详解如下
import org.springframework.beans.factory.config.BeanDefinition;import java.util.ArrayList;
import java.util.List;/*** author Kissship* site www.Kissship.com* company xxx公司* create 2023-08-18-14:17*/
public class Demo1 {//初始化Beanpublic static void main(String[] args) throws ClassNotFoundException {
// 2.BeanDefinitionReader解析配置的JavaBean得到Beandefinition最终得到ListBeanDefinition集合ListBeanDefinition beans new ArrayList();//BeanDefinitionReader把spring-context.xml中所有的bean标签都解析成了List集合for (BeanDefinition bean : beans) {
// 4.Spring中的BeanFactory会通过ListBeanDefinition集合遍历初始化所有的JavaBean对象String beanClassName bean.getBeanClassName();//得到的就是spring-context.xml中bean标签中class里的值Class.forName(beanClassName);//将配置的所有JavaBean进行反射实例化}}
}
如果自己的JavaBean需要调动Spring上下文中的资源(方法或属性)那么需要实现*Aware感知接口比如BeanDefinition实现了BeanNameAware、ApplicationContextAware接口具体详解如下 Aware接口
实现Aware接口 1.2思考
那么现在有个问题当我们的Spring容器初始化Bean完成之后我们可能还需要加工一下即进行再初始化。因为并不是每一个类都是我们自己写的。也许我们需要用别人的类内容然后在此基础上再进行拓展。那么在此时我们能改动别人写的类里面的源码吗不能。因为这样有可能影响到其他的功能这时候我们的解决办法就是自己写一个类去继承别人的类然后进行再一波初始化我们这里以BaseDao为例
BaseDao为父类MyBaseDao为子类 我们需要在继承BaseDao方法后在子类中进行初始化方法的重写即再一次初始化具体如下
package com.kissship.beanlife;/*** author Kissship* site www.Kissship.com* company xxx公司* create 2023-08-18-15:58*/
//继承原本的BaseDao
public class MyBaseDao extends BaseDao{public MyBaseDao(){//重写初始化方法super();System.out.println(初始化...);}
}那么在此时如果我们在初始化之后不满意在初始化之后想修改Bean的内容可以利用BeanPostProcessor后置处理器来完成。这时候可以在Bean对象实例化和引入注入完毕后在显示调用初始化方法的前后添加自定义逻辑。类似于AOP的环绕通知环绕通知不了解的可以通过下面链接进行跳转至对应博客界面如下
Kissship的博客Spring之AOP篇https://blog.csdn.net/weixin_74263417/article/details/132340241?spm1001.2014.3001.5501那么到这里我们就完成了Bean的创建工作。
2.Bean的单例与多例选择 1.在Spring中JavaBean默认是单例的但是可以配置多例。 2.单例的优点节约内存。弊端有变量污染。 多例的优点无变量污染。弊端极其消耗内存。 3.单例JavaBean是跟着spring上下文初始化的容器生对象生容器死对象死此处对象指JavaBean。 多例JavaBean在使用时才会创建销毁跟着jvm走。 4.第三点并不绝对正确个别情况会有所个例。 2.1论证单例与多例优缺点
准备工作
ParamAction
package com.kissship.beanlife;import java.util.List;public class ParamAction {private int age;private String name;private ListString hobby;private int num 1;// private UserBiz userBiz new UserBizImpl1();public ParamAction() {super();}public ParamAction(int age, String name, ListString hobby) {super();this.age age;this.name name;this.hobby hobby;}public void execute() {// userBiz.upload();// userBiz new UserBizImpl2();System.out.println(this.num this.num);System.out.println(this.name);System.out.println(this.age);System.out.println(this.hobby);}
}InstanceFactory(Bean工厂)
package com.kissship.beanlife;public class InstanceFactory {public void init() {System.out.println(初始化方法);}public void destroy() {System.out.println(销毁方法);}public void service() {System.out.println(业务方法);}
}spring-context.xml进行配置生命周期部分
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansdefault-autowirebyTypexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd!-- ioc的javabean--
!-- 凡是在Spring配置文件spring-context.xml中配置,那么该类javabean就交给了Spring容器管理--bean classcom.kissship.ioc.web.UserAction iduserActionproperty nameuserService refuserService/property
!-- constructor-arg nameuname value扎克 /constructor-arg--
!-- constructor-arg nameage value18 /constructor-arg--
!-- constructor-arg namehobby--
!-- list--
!-- value唱跳/value--
!-- valueRap/value--
!-- value篮球/value--
!-- /list--
!-- /constructor-arg--/beanbean classcom.kissship.ioc.web.GoodsAction idgoodsActionproperty nameuserService refuserServiceImpl1/property
!-- property namegname value小文/property--
!-- property nameage value19/property--
!-- property namepeoples--
!-- list--
!-- value印度飞饼/value--
!-- value意大利炮/value--
!-- value北京烤鸭/value--
!-- value墨西哥卷/value--
!-- /list--
!-- /property--/beanbean classcom.kissship.ioc.service.impl.UserServiceImpl2 iduserService/beanbean classcom.kissship.ioc.service.impl.UserServiceImpl1 iduserServiceImpl1/bean!-- aop相关的Javabean--!--目标对象--bean classcom.kissship.aop.biz.impl.BookBizImpl idbookBiz/bean!--通知--bean classcom.kissship.aop.advice.MyMethodBeforeAdvice idmethodBeforeAdvice/beanbean classcom.kissship.aop.advice.MyAfterReturningAdvice idmyAfterReturningAdvice/beanbean classcom.kissship.aop.advice.MyMethodInterceptor idmyMethodInterceptor/beanbean classcom.kissship.aop.advice.MyThrowsAdvice idmyThrowsAdvice/beanbean classorg.springframework.aop.support.RegexpMethodPointcutAdvisor idregexpMethodPointcutAdvisorproperty nameadvice refmyAfterReturningAdvice/propertyproperty namepattern value.*buy/property/bean!--代理--bean classorg.springframework.aop.framework.ProxyFactoryBean idbookProxy
!-- 配置目标对象--property nametarget refbookBiz/property
!-- 配置代理接口目标对象的接口--property nameproxyInterfaceslistvaluecom.kissship.aop.biz.IBookBiz/value/list/property
!-- 配置通知--property nameinterceptorNameslistvaluemethodBeforeAdvice/value
!-- valuemyAfterReturningAdvice/value--valueregexpMethodPointcutAdvisor/valuevaluemyMethodInterceptor/valuevaluemyThrowsAdvice/value/list/property/bean!-- Spring的生命周期--bean classcom.kissship.beanlife.ParamAction idparamActionconstructor-arg namename value刘三金/constructor-argconstructor-arg nameage value19/constructor-argconstructor-arg namehobbylistvalue来自星星的哥/valuevalue天空一声巨响/valuevalue劳资闪亮登场/value/list/constructor-arg/beanbean classcom.kissship.beanlife.InstanceFactory idinstanceFactoryscopeprototype init-methodinit destroy-methoddestroy/bean/beans
测试类Demo2
package com.kissship.beanlife;import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;/** spring bean的生命週期* spring bean的單例多例*/
public class Demo2 {// 体现单例与多例的区别Testpublic void test1() {ClassPathXmlApplicationContext applicationContext new ClassPathXmlApplicationContext(/spring-context.xml);
// ApplicationContext applicationContext new ClassPathXmlApplicationContext(/spring-context.xml);ParamAction p1 (ParamAction) applicationContext.getBean(paramAction);ParamAction p2 (ParamAction) applicationContext.getBean(paramAction);// System.out.println(p1p2);p1.execute();p2.execute();// 单例时容器销毁instanceFactory对象也销毁多例时容器销毁对象不一定销毁applicationContext.close();}// 体现单例与多例的初始化的时间点 instanceFactoryTestpublic void test2() {ApplicationContext applicationContext new ClassPathXmlApplicationContext(/spring-context.xml);}// BeanFactory会初始化bean对象但会根据不同的实现子类采取不同的初始化方式// 默认情况下bean的初始化单例模式立马会执行但是此时XmlBeanFactory作为子类单例模式下容器创建bean依赖没有初始化只有要获取使用bean对象才进行初始化Testpublic void test3() {// ClassPathXmlApplicationContext applicationContext new// ClassPathXmlApplicationContext(/spring-context.xml);Resource resource new ClassPathResource(/spring-context.xml);BeanFactory beanFactory new XmlBeanFactory(resource);
// InstanceFactory i1 (InstanceFactory) beanFactory.getBean(instanceFactory);}}执行Demo2结果如下 那么我们换上多例后会是什么结果
具体实操在spring-context.xml中ParamAtion的Bean配置的class属性里加上scope属性并赋值多例(原型模式) 如下 修改后我们继续执行Demo2测试类看看效果 2.2论证初始化时间点
Demo2里已经写了体现单例与多例的初始化时间点的方法所以我们只需要在spring-context.xml中给它定一个多例的属性值然后测试看效果即可xml代码如下
bean classcom.kissship.beanlife.InstanceFactory idinstanceFactoryscopeprototype init-methodinit destroy-methoddestroy/bean
然后我们运行Demo2看看效果如下 紧接着我们换成单例如下
bean classcom.kissship.beanlife.InstanceFactory idinstanceFactoryscopesingleton init-methodinit destroy-methoddestroy/bean
执行方法看效果如下 那么现在问题又来了虽然验证了单例与多例的初始化时间点但是看不出到底是不是使用Spring创建的那么现在我们上代码验证看看结果。刚刚我们在演示时多例并没有执行初始化方法现在我们把xml文件里的单例改成多例然后再Demo2测试类中加上以下代码 然后再运行一次看效果 2.3个例演示
BeanFactory会初始化bean对象但会根据不同的实现子类采取不同的初始化方式。
默认情况下bean的初始化单例模式会立马执行但是此时XmlBeanFactory作为子类单例模式下容器创建bean依赖没有初始化·只有要获取使用bean对象才进行初始化。
验证 1.先把xml多例模式改为单例然后运行Test2方法再运行Test3方法比较结果。 2.然后把Test3注释的代码部分放开再执行比较结果。 运行Test2的结果(先注释论证是否为Sprring创建新增的代码再运行) 运行Test3的结果 然后取消注释如下 再执行一次Test3效果如下 最后Spring之bean的生命周期就到这里祝大家在敲代码的路上一路通畅!
感谢大家的观看 !