1. 程式人生 > >Java框架學習_Spring(三)Spring_AOP底層實現:JDK動態代理和Cglib動態代理

Java框架學習_Spring(三)Spring_AOP底層實現:JDK動態代理和Cglib動態代理

AOP和IOC是Spring的兩大思想,AOP即面向切面程式設計,和OOP相輔相成,具體請看: AOP(面向切面程式設計)

這裡學習一下它的底層實現方法----動態代理,動態代理關鍵的是代理,就像你去公司辦事,你有什麼需求,不可能直接找到 boss(原始碼),而是通過祕書(代理)來實現你的需求,Boss辦事也是通過代理實現的,(java中很多的思想就是解耦和,將原始碼和業務實現分開,儘量不要去動原始碼,方便程式碼複用和管理


1、JDK動態代理: 只能對實現了介面的類(或者直接對這個介面)進行代理
這一點很重要,如果JDK要對一個類進行動態代理,那麼這個類必須是實現了一個介面,比如UserDaoImpl implement UserDao,這個時候才能對UserDaoImpl或者直接對UserDao進行代理

具體代理方法如下:

package cn.nupt.demo01.UserDao;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//建立代理類
public class ProxyTest implements InvocationHandler {

	private UserDao userDao;

	// 建構函式,傳入我要代理的類,初始化代理類
	public ProxyTest(UserDao userDaoTrue)
{ this.userDao = userDaoTrue; } // 建立代理類的例項:userDao.getClass().getInterfaces()就是獲得這個介面實現的所有介面 public UserDao createProxy() { // 返回的是Object,強轉到介面或實現類 // 引數1:類載入器; 引數2:所有實現的介面集合;引數三:實現了InvocationHandler的類,在這裡就是本身 UserDao userDaoProxy = (UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader
(), userDao.getClass().getInterfaces(), this); return userDaoProxy; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("save".equals(method.getName())) { // 需要增強的方法 System.out.println("加入動態代理實現"); // 通過反射返回這個方法的實現 return method.invoke(userDao, args); } return method.invoke(userDao, args); } }

建立測試類:

	@Test
	public void test04() {
		UserDao daoImpl = new UserDaoImpl();
		UserDao proxy = new ProxyTest(daoImpl).createProxy();
		
		proxy.save();
		proxy.delete();
	}
	
輸出:
	儲存使用者
	加入動態代理實現
	刪除使用者

2、Cglib動態代理: 可以直接對類代理
Cglib是第三方類庫,需要導包,這裡只需要將Spring的核心包匯入就行了(見前面Spring配置)

具體代理方法如下:

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class ProxyDemo implements MethodInterceptor {

	private Coustomer coustomer;

	public ProxyDemo(Coustomer coustomer) {
		this.coustomer = coustomer;
	}

	public Coustomer createProxy() {
		// 1、建立cglib的核心類物件
		Enhancer enhancer = new Enhancer();
		// 2、設定父類
		enhancer.setSuperclass(coustomer.getClass());
		// 3、設定回撥(相當於InvocationHandler)
		enhancer.setCallback(this);
		// 4、建立代理物件並返回
		Coustomer proxy = (Coustomer) enhancer.create();
		return proxy;

	}

	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		if ("hehe".equals(method.getName())) {
			System.out.println("增強了");
			return methodProxy.invokeSuper(proxy, args);
		}

		return methodProxy.invokeSuper(proxy, args);
	}

}

測試類:

@Test
	public void test() {
		Coustomer coustomer = new Coustomer();
		Coustomer proxy = new ProxyDemo(coustomer).createProxy();
		proxy.haha();
		proxy.hehe();
	}
	
輸出:
	haha
	增強了
	hehe