• 4.BeanPostProcessor 后处理Bean


     Bean种类

     普通bean:之前操作的都是普通bean<bean id="" class="A"> spring直接创建A实例,并返回

     FactoryBean:是一个特殊的bean,具有工厂生成对象能力,只能生成特定的对象。

    bean必须使用 FactoryBean接口,此接口提供方法 getObject() 用于获得特定bean

    <bean id="" class="FB"> 先创建FB实例,使用调用getObject()方法,并返回方法的返回值

    FB fb = new FB();

    return fb.getObject();

    l BeanFactory FactoryBean 对比?

    BeanFactory:工厂,用于生成任意bean

    FactoryBean:特殊bean,用于生成另一个特定的bean。例如:ProxyFactoryBean ,此工厂bean用于生产代理。<bean id="" class="....ProxyFactoryBean"> 获得代理对象实例。AOP使用

     作用域

    取值:

    singleton 单例,默认值。

    prototype 多例,每执行一次getBean将获得一个实例。例如:struts整合spring,配置action多例。

    配置信息

    <bean id="" class=""  scope="">

    <bean id="userServiceId" class="com.itheima.d_scope.UserServiceImpl" 
    
    scope="prototype" ></bean>

     

    生命周期

     初始化和销毁

     目标方法执行前后执行后,将进行初始化或销毁。

    <bean id="" class="" init-method="初始化方法名称"  destroy-method="销毁的方法名称">

    spring配置

    <!--  
    
    init-method 用于配置初始化方法,准备数据等
    
    destroy-method 用于配置销毁方法,清理资源等
    
    -->
    
    <bean id="userServiceId" class="com.itheima.e_lifecycle.UserServiceImpl" 
    
    init-method="myInit" destroy-method="myDestroy" ></bean>

    测试

    @Test
    
    public void demo02() throws Exception{
    
    //spring 工厂
    
    String xmlPath = "com/itheima/e_lifecycle/beans.xml";
    
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
    
    UserService userService = (UserService) applicationContext.getBean("userServiceId");
    
    userService.addUser();
    
     
    
    //要求:1.容器必须close,销毁方法执行; 2.必须是单例的
    
    // applicationContext.getClass().getMethod("close").invoke(applicationContext);
    
    // * 此方法接口中没有定义,实现类提供
    
    applicationContext.close();
    
     
    
    }

     

     BeanPostProcessor 后处理Bean

    spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after() 。 配置<bean class="">

    l Factory hook(勾子) that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.

    l spring提供工厂勾子,用于修改实例对象,可以生成代理对象,是AOP底层。

    模拟

    A a =new A();

    a = B.before(a) --> a的实例对象传递给后处理bean,可以生成代理对象并返回。

    a.init();

    a = B.after(a);

    a.addUser(); //生成代理对象,目的在目标方法前后执行(例如:开启事务、提交事务)

    a.destroy()

    1.编写实现类

    MyBeanPostProcessor.java
    package com.jd.lifecycle;
    
    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;
    
    /**
     * @author weihu
     * @date 2018/8/12/012 23:15
     */
    public class MyBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
            System.out.println("前方法:"+o);
            return o;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
            System.out.println("后方法:"+o);
            //o目标对象
            //生成jdk代理
            return Proxy.newProxyInstance(MyBeanPostProcessor.class.getClassLoader(),
                    o.getClass().getInterfaces(), new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            System.out.println("---开启事物-----");
    
                            //执行目标方法
                            Object obj = method.invoke(o, args);
                            System.out.println("-----提交事物-------");
                            return obj;
                        }
                    });
        }
    }
    UserService.java
    package com.jd.lifecycle;
    
    public interface UserService {
        
        public void addUser();
    
    }
    UserServiceImpl.java
    package com.jd.lifecycle;
    
    public class UserServiceImpl implements UserService {
    
        @Override
        public void addUser() {
            System.out.println("lifecycle add user");
        }
    
        public void myInit(){
            System.out.println("初始化");
        }
    
        public void myDestroy(){
            System.out.println("销毁");
        }
    
    }

    beans.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <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">
    
        <!--
            init-method 用于配置初始化方法,准备数据等
            destroy-method 用于配置销毁方法,清理资源等
        -->
        <bean id="userServiceId" class="com.jd.lifecycle.UserServiceImpl" init-method="myInit"
        destroy-method="myDestroy"></bean>
    
        <!--将后处理的实现类注册给spring-->
        <bean class="com.jd.lifecycle.MyBeanPostProcessor"></bean>
        
    </beans>
    TestCycle.java
    package com.jd.lifecycle;
    
    import org.junit.Test;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * @author weihu
     * @date 2018/8/12/012 23:24
     */
    public class TestCycle {
    
        @Test
        public void testProx(){
            String xmlPath="com/jd/lifecycle/beans.xml";
            ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
            UserService userService = (UserService) applicationContext.getBean("userServiceId");
            userService.addUser();
    
            //要求:1.容器必须close,销毁方法执行; 2.必须是单例的
    //        applicationContext.getClass().getMethod("close").invoke(applicationContext);
            // * 此方法接口中没有定义,实现类提供
            applicationContext.close();
        }
    }
  • 相关阅读:
    shell编程-项目部署(优化篇)
    数据库相关
    python基础面试
    scrapy爬取数据进行数据库存储和本地存储
    C# 对字符串操 替换数字 替换非数字 去除首尾字符 长沙
    还在为删除集合中的相同项而烦恼吗?
    C#之Task&匿名方法
    如何在火狐里面实现如下功能
    valueOf和toString曾经欺骗过你吗?
    JS 实现Json查询方法
  • 原文地址:https://www.cnblogs.com/weihu/p/9465556.html
Copyright © 2020-2023  润新知