4.BeanPostProcessor 后处理Bean

Posted weihu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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();
    }
}

 

以上是关于4.BeanPostProcessor 后处理Bean的主要内容,如果未能解决你的问题,请参考以下文章

gm图片处理器:The gm/convert binaries can't be found

mysql 存储数据取出后操作 com.alibaba.fastjson.JSONObject cannot be cast to

绝地求生大逃杀BE启动失败,应用程序无法正常启动

ValueError: total size of new array must be unchanged

spring-security中的 No AuthenticationEntryPoint could be established异常处理.

ORA-16009 remote archive log destination must be a STANDBY database