可以配置Bean的这个类的初始化和销毁的方法。

如何销毁这个bean?销毁必须得手动地关闭掉容器才行。而且销毁必须是在scope="singleton"下才有效。因为如果你scope="prototype"它就会生成N多的实例。它就不知道销毁哪个实例了。


Bean的生命周期。在Spring创建这个Bean的过程中总共有11个步骤。

 所以Spring在生成Bean的生命周期的过程中总共有11个步骤。


需求:假设我有N多个Service,都需要在add()方法之前作权限校验,那么N个add方法都需要做权限校验.你每个类都打开,每个add()方法之前都加上权限校验的代码。特别麻烦。如果说不想要了,还得50个类都打开全部去掉。特别麻烦。

有了后处理bean之后可以把代码加在后处理bean上,不影响业务逻辑,不想要的时候最多在配置文件中把后处理bean去掉,想要的时候又在配置文件中把后处理bean加进来。


Spring类完整的生命周期记不记住无所谓,关键是后处理bean上。


package cn.itcast.spring3.demo4;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanPostProcessor implements BeanPostProcessor{
/**
* bean:实例对象
* beanName:在配置文件中配置的类的标识.(就是id或者是name,如果你没id,name也行)
*/
//关键是第五步和第八步是怎么增强的.
//第五步和第八步只要你有一个类创建它都会执行的.整个生命周期不不用都记下来,关键是第五步和第八步.这两个可以做一些增强的操作.
//Spring有很多内容都是基于后处理bean:BeanPostProcessor的.BeanPostProcessor,都是基于它的.
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException { System.out.println("第五步:初始化之前执行....");//初始化之前执行
return bean;//什么都没干,直接返回bean.直接返回bean代表根本没增强,什么事都没干.
} public Object postProcessAfterInitialization(final Object bean, String beanName)
throws BeansException {
System.out.println("第八步:初始化后执行....");
//有bean对象,有它的实例 实例化一个,相当于又创建一个helloService,现在要增强它
//动态代理:Proxy.newProxyInstance()对实现接口的类生成代理 增强一个类的某个方法的时候有三种方式:继承、装饰者、动态代理。其中动态代理是最为灵活的一种方式
//jdk的动态代理是必须对实现接口的类生成代理 但是Spring里面有别的办法
//newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
//类的加载器,interfaces类实现的接口,InvocationHandler类的处理器
//if(bean.getClass().getName().equals("CustomerServiceImpl")){//调CustomerService里面的任何一个方法都相当于执行invoke
//if(bean.getClass().getName().equals("customerService")){//调CustomerService里面的任何一个方法都相当于执行invoke
//if(bean.getClass().getName().equals("CustomerService")){//调CustomerService里面的任何一个方法都相当于执行invoke
//if(beanName.equals("CustomerService")){//配置文件里面叫customerService
if(beanName.equals("customerService")){
Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler(){
//在外面调用任何一个方法都相当于执行我们这里面的这个invoke()方法
//要是只想对CustomerService增强,不想对别的Service增强,那就在这里加个判断,否则它是对所有的类都执行这个后处理bean的.
//调用目标方法的时候,调用invoke方法.
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//对它里面进行增强
//return method.invoke(bean,args);//相当于是没有进行增强
//如果不是对所有方法都进行增强,判断
if("add".equals(method.getName())){//是add()才增强
//进行时间监控或者是权限校验都可以
System.out.println(System.currentTimeMillis());//时间监控
//System.out.println("权限校验.....");
Object result = method.invoke(bean, args);
System.out.println(System.currentTimeMillis());//时间监控
return result;
}
return method.invoke(bean, args);//不是add()方法就不进行增强
} });//返回实现这个接口的一个代理
//第二个参数得到这个类实现的所有的接口
//第三个参数是一个处理器 处理器它是一个接口 两种办法 第一种办法你自己写个类实现这个接口,第二种办法直接匿名内部类
return proxy;//如果这个类是CutomerService,直接返回一个代理对象
} return bean;//其他的类不增强,return bean;
//放开if,不管你哪个类都会给你生成代理,给你增强
}
}
package cn.itcast.spring3.demo4;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; public class CustomerServiceImpl implements CustomerService,BeanNameAware,ApplicationContextAware,InitializingBean,DisposableBean{
//演示CustomerService完整的生命周期 //第一步是实例化这个bean,那样就会调用它的构造方法
//第一步:只要一加载配置文件就帮我们创建这个类了。
@SuppressWarnings("unused")
private String name; public void setName(String name) {
System.out.println("第二步:属性的注入.");
this.name = name;
} public CustomerServiceImpl() {
super();
System.out.println("第一步:实例化类.");
} public void add(){//第九步:执行业务逻辑
System.out.println("添加客户....");
} public void find(){//第九步:执行业务逻辑
System.out.println("查询客户.....");
} public void setBeanName(String name) {
System.out.println("第三步:注入配置的类的名称"+name);//什么是类的名称?就是那个id
// <bean id="customerService" class="cn.itcast.spring3.demo4.CustomerService">
//就是我们在Spring中对这个类起了一个id。它就会把这个名字给你注入到这个程序里面,让我们这个类CustomerService了解Spring的容器。它就把你配置的那个id给你传过来了。 } //第四步也是让我们这个类来了解Spring容器,只不过它是把工厂注入进来了。它是把ApplicationContext注入进来了。
//它就让我们本身这个类了解Spring这个容器
//第三步和第四步都是为了让我们这个类来了解Spring容器。
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
System.out.println("第四步:注入applicationContext"+applicationContext);
} public void afterPropertiesSet() throws Exception {
System.out.println("第六步:属性设置后执行....."); } public void setup(){
System.out.println("第七步:调用手动设置的初始化方法...."); } public void destroy() throws Exception {
System.out.println("第十步:调用销毁的方法...."); }
public void teardown(){ System.out.println("第十一步:调用手动销毁的方法....");
}
}
package cn.itcast.spring3.demo4;

public interface CustomerService {
public void add();
public void find(); }
package cn.itcast.spring3.demo4;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; @SuppressWarnings("unused")
public class SpringTest4 { @Test
//Bean完整的生命周期 public void demo1(){
//ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); //CustomerServiceImpl customerService = (CustomerServiceImpl) applicationContext.getBean("customerService");
CustomerService customerService = (CustomerService) applicationContext.getBean("customerService");
customerService.add();
customerService.find();
applicationContext.close(); } }
<?xml version="1.0" encoding="UTF-8"?>
<!-- 别去schema,schema是文件,本地的文件,你得引那个头 --> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- demo1快速入门================================================= -->
<!-- 把接口和实现类在这个配置文件中配置,有了实现类的全路径之后到时候才能用工厂反射 --> <!-- 通过一个<bean>标签来设置类的信息,通过id属性为类起个标识. -->
<!-- 接口,实现类,配置文件也都有了 -->
<!-- 现在有一个工厂Spring为我们提供好了,其实就是解析这个XML文件 -->
<!-- 这个工厂你自己写会不会写?你用dom4j找里面的bean标签,找到class的属性值,然后就可以Class.forName()反射生成类的实例.其实Spring
也是这么做的,只不过工厂由Spring提供好了
-->
<bean id="helloService" class="cn.itcast.spring3.demo1.HelloServiceImpl">
<!-- 使用<property>标签注入属性
value指的是普通值
ref指的是对象
-->
<property name="info" value="传智播客"></property>
</bean>
<!-- demo1快速入门 -->
<!-- demo2Bean的实例化 -->
<!-- 默认情况下使用的就是无参数的构造方法. -->
<!--
<bean id="bean1" class="cn.itcast.spring3.demo2.Bean1"></bean>
-->
<!--
<bean name="bean1" class="cn.itcast.spring3.demo2.Bean1"></bean>
-->
<!-- 第二种使用静态工厂实例化 不能写class了,因为现在不是由Spring直接帮你创建对象了-->
<!--
<bean id="bean2" class="cn.itcast.spring3.demo2.Bean2Factory" factory-method="getBean2"></bean>
-->
<!-- 第三种使用实例工厂实例化 -->
<!--
<bean id="bean3" factory-bean="bean3Factory" factory-method="getBean3"></bean>
-->
<!-- 要先把Bean3Factory实例化 -->
<!--
<bean id="bean3Factory" class="cn.itcast.spring3.demo2.Bean3Factory"></bean>
-->
<!-- demo2Bean的实例化====================== end--> <!-- demo3Bean的作用范围======================= -->
<!--
<bean id="customer" class="cn.itcast.spring3.demo3.Customer" scope="prototype"></bean>
-->
<!--
<bean id="product" class="cn.itcast.spring3.demo3.Product" init-method="setup" destroy-method="teardown" scope="singleton">
<property name="name" value="空调">-->
<!-- 把Product类的属性name注入进来 -->
<!--
</property>
</bean>
--> <!-- demo4Bean的生命周期======================= -->
<bean id="customerService" class="cn.itcast.spring3.demo4.CustomerServiceImpl" init-method="setup" destroy-method="teardown"> <property name="name" value="itcast"></property>
</bean>
<!-- 后处理Bean是由Spring容器自动调用不用你管,我们起个id是为了我们在程序中去获得它。但是这个类不用由我们获得, 由Spring自动调用。cn.itcast.spring3.demo4.MyBeanPostProcessor是后处理Bean-->
<bean class="cn.itcast.spring3.demo4.MyBeanPostProcessor"></bean> </beans>

day38 09-Spring类的完整生命周期及后处理Bean的更多相关文章

  1. Bean 的生命周期 之 后处理Bean

    这里先把Bean 的生命周期总结一下,然后引出后处理Bean 首先,Bean 的生命周期总共有11步: 1.instantiate bean对象实例化 2.populate properties 封装 ...

  2. spring Bean的完整生命周期

    spring 容器中的bean的完整生命周期一共分为十一步完成. 1.bean对象的实例化 2.封装属性,也就是设置properties中的属性值 3.如果bean实现了BeanNameAware,则 ...

  3. 一张图搞懂Spring bean的完整生命周期

    一张图搞懂Spring bean的生命周期,从Spring容器启动到容器销毁bean的全过程,包括下面一系列的流程,了解这些流程对我们想在其中任何一个环节怎么操作bean的生成及修饰是非常有帮助的. ...

  4. Spring注解开发系列Ⅲ --- 生命周期

    Bean的生命周期 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解. 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: S ...

  5. 浅尝Spring注解开发_Bean生命周期及执行过程

    Spring注解开发 浅尝Spring注解开发,基于Spring 4.3.12 包含Bean生命周期.自定义初始化方法.Debug BeanPostProcessor执行过程及在Spring底层中的应 ...

  6. Spring学习10- bean的生命周期(阿里面试题目两次面试均提到)

    找工作的时候有些人会被问道Spring中Bean的生命周期,其实也就是考察一下对Spring是否熟悉,工作中很少用到其中的内容,那我们简单看一下. 在说明前可以思考一下Servlet的生命周期:实例化 ...

  7. 一次性讲清楚spring中bean的生命周期之三:bean是如何实例化的

    在前面的两篇博文<一次性讲清楚spring中bean的生命周期之一:getSingleton方法>和<一次性讲清楚spring中bean的生命周期之二:FactoryBean的前世今 ...

  8. Application类-应用程序生命周期

    1.创建Application对象 新建WPF程序后,排除掉WPF自动创建的App.xaml,我们自定义一个类,在该类的Main()方法中,创建Application对象,然后调用创建一个窗口对象,最 ...

  9. 第四章 Spring.Net 如何管理您的类___对象的生命周期链

    各位,实在不好意思,因为有事,博客几天没更新了.前面有童鞋提到,配置 Objects.xml 路径的相关问题,这些东西是 IResource 接口的一些内容.在下一章会详细介绍. 传统的Net应用中, ...

随机推荐

  1. Mac系统下安装Vue-cli详细步骤

    Vue-cli安装 因为是mac系统,所以和视频里老师讲的有些许不同. 1.首先打开终端 按照老师的操作,首先检查node版本 下面是我的操作 打开终端,输入命令 node -v 我去,找不到node ...

  2. 图书-技术-SpringBoot:《Spring Boot2 + Thymeleaf 企业应用实战》

    ylbtech-图书-技术-SpringBoot:<Spring Boot2 + Thymeleaf 企业应用实战> <Spring Boot 2+Thymeleaf企业应用实战&g ...

  3. PAT甲级——【牛客练习A1004】

    题目描述 An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For ex ...

  4. 使用Geomagic处理点云一般步骤

    Geomagic处理几百万级数量点云一般处理步骤:     这只是一般的步骤, 对于处理结果要求不高的操作过程:高手请自行略过: 也许Geomagic的版本不同,但操作一般都是一样的顺序:  操作步骤 ...

  5. Top- Linux必学的60个命令

    1.作用 top命令用来显示执行中的程序进程,使用权限是所有用户. 2.格式 top [-] [d delay] [q] [c] [S] [s] [i] [n] 3.主要参数 d:指定更新的间隔,以秒 ...

  6. 如何做系列(3)-Java数据类型和MySql数据类型对照表

    类型名称 显示长度 数据库类型 JAVA类型 JDBC类型索引(int) 描述             VARCHAR L+N VARCHAR java.lang.String 12   CHAR N ...

  7. python基础-三元表达式/列表推导式/生成器表达式

    1.三元表达式:如果成立返回if前的内容,如果不成立返回else的内容 name=input('姓名>>: ') res='SB' if name == 'alex' else 'NB' ...

  8. vue 学习 一

    1.实例: var vm = new Vue({ el: '#example', data: { a:1 }, created: function () { // `this` 指向 vm 实例 co ...

  9. BZOJ3907 网格 卡特兰数

    题目描述 某城市的街道呈网格状,左下角坐标为A(0, 0),右上角坐标为B(n, m),其中n >= m. 现在从A(0, 0)点出发,只能沿着街道向正右方或者正上方行走,且不能经过图示中直线左 ...

  10. Navicat12.1.7破解教程

    https://blog.csdn.net/qq_39344689/article/details/85161342