1. 程式人生 > >關於後處理Bean作用目標類的控制

關於後處理Bean作用目標類的控制

BeanPostProcessor,後處理Bean,在applicationContext.xml中配置時,它將會作用於全部的目標類。

實現其作用於某個目標類可以使用“beanName”屬性控制。

package com.spring.proxy;

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 {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		/*if ("userDao".equals(beanName)) {
			return bean;
		}*/
		System.out.println("初始化前" + beanName);
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(final Object bean, String beanName)
			throws BeansException {
		/*if ("userDao".equals(beanName)) {
			return bean;
		}*/
		System.out.println("初始化後" + beanName);
		return Proxy.newProxyInstance(MyBeanPostProcessor.class.getClassLoader(), bean.getClass().
				getInterfaces(), new InvocationHandler() {
			
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				System.out.println("--------->開啟事務" + bean.getClass().getName());
				Object invoke = method.invoke(bean, args);
				System.out.println("--------->關閉事務" + bean.getClass().getName());
				return invoke;
			}
		});
	}

}

以上執行步驟:

  1. 將userDao的例項物件傳給後處理Bean,在其初始化前執行postPorcessorBeforeInitialization方法,列印了“初始化前userDao”;
  2. 初始化後執行postProcessorAfterInitialization方法;
  3. 在postProcessorAfterInitialization方法中先列印了“初始化後userDao”;
  4. 列印完文字後返回了userDao的代理物件;
  5. 其後userService重複userDao進行的步驟1、步驟2、步驟3,即在before方法中先列印“初始化前userService”,初始化時列印“初始化userServiceImpl”,最後在after方法中列印“初始化後userService”;
  6. 同時在after方法中返回userService的代理物件;
  7. 執行類TestClass中的ius.addUser()時,列印“------>開啟事務com。。。UserServiceImpl”,然後呼叫bean(即UserServiceImpl)的addUser();
  8. 執行addUser方法中的iud.insert(),此時userDao的代理物件中的方法執行並列印“------>開啟事務com。。。UserDaoImpl”,再呼叫其insert()方法列印“insert user into table successfully”,
  9. 。。。略

控制後處理Bean的作用目標,如上被註釋程式碼,開啟註釋即可

TestClass程式碼:

package com.spring.proxy;

import java.lang.reflect.InvocationTargetException;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestClass {
	@Test
	public void test1() throws IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, 
									NoSuchMethodException {
		String xmlPath = "com/spring/proxy/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		IUserService ius = applicationContext.getBean("userService", IUserService.class);
		ius.addUser();
		applicationContext.getClass().getMethod("close").invoke(applicationContext);
	}
}
UserServiceImpl程式碼:
package com.spring.proxy;

public class UserServiceImpl implements IUserService {

	private IUserDao iud = null;
	public void setIUserDao(IUserDao iud) {
		this.iud = iud;
	}

	@Override
	public void addUser() {
		iud.insert();
	}
	public void myInitial() {
		System.out.println("初始化UserServiceImpl");
	}
	public void myDestroy() {
		System.out.println("銷燬UserServiceImpl");
	}
}

UserDaoImpl程式碼:

package com.spring.proxy;

public class UserDaoImpl implements IUserDao {

	@Override
	public void insert() {
		System.out.println("insert user into table successfully");
	}

}