1. 程式人生 > >4.BeanPostProcessor 後處理Bean

4.BeanPostProcessor 後處理Bean

獲得 機制 roman tcl style mage lose pac pan

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="銷毀的方法名稱">

1 spring配置

<!--  

init-method 用於配置初始化方法,準備數據等

destroy
-method 用於配置銷毀方法,清理資源等 --> <bean id="userServiceId" class="com.itheima.e_lifecycle.UserServiceImpl" init-method="myInit" destroy-method="myDestroy" ></bean>

2 測試

@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