Spring AOP底層實現的兩種代理機制
阿新 • • 發佈:2021-01-30
技術標籤:筆記
JDK\Cglib 的動態代理
1、dao
package com.test.dao;
import java.util.List;
import com.test.domain.User;
public interface UserDao {
List<User> findAllUser();
void save();
}
2、dao實現
package com.test.dao.impl;
import java.util.List;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import com.test.dao.UserDao;
import com.test.domain.User;
//可以不寫名字;使用@Component註解就相當於在配置中寫了一個bean
//@Component(value = "userdao")
@Repository(value = "userdao")
//@Repository //不寫value 那麼預設的就是當前類名的首字母小寫userDaolmpl
public class UserDaolmpl implements UserDao {
public List<User> findAllUser() {
// TODO Auto-generated method stub
System.out.println("User");
return null;
}
public void save() {
System.out.println("User");
}
}
JDK 的動態代理(實現InvocationHandler)
- 針對實現了介面的類產生代理.
package springpro1;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;
import com.test.dao.UserDao;
public class MyJDKProxy implements InvocationHandler{
//將代理類傳進來,以建構函式的形式傳
private UserDao userDao;
//有參構造
public MyJDKProxy(UserDao userDao) {
this.userDao = userDao;
}
//編寫工具方法:生成代理:
public UserDao createProxy(){
//用原來的真實類來產生它的代理類
UserDao userDaoProxy=(UserDao)Proxy.newProxyInstance(userDao.getClass().getClassLoader(),userDao.getClass().getInterfaces(), this);
return userDaoProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("save".equals(method.getName())){
System.out.println("許可權校驗================");
}
return method.invoke(userDao, args);
}
}
Cglib 的動態代理(實現MethodInterceptor)
- 針對沒有實現介面的類產生代理. 應用的是底層的位元組碼增強的技術 生成當前類的子類物件
package springpro1;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
//CGLIB代理類
public class LogCglibProxy implements MethodInterceptor{
private Object target; // 代理的目標物件
/**
* 建立代理物件
* @param <T>
* @param target 目標物件
*/
@SuppressWarnings("unchecked")
public <T> T createProxyInstance(T target) {
this.target = target;
Enhancer enhancer = new Enhancer(); // 該類用於生成代理物件
enhancer.setSuperclass(target.getClass()); // 設定父類
enhancer.setCallback(this); // 設定回撥物件為自己這個物件
return (T) enhancer.create(); // 建立代理物件並返回
}
/**
* @param proxy 目標物件代理類的例項
* @param method 代理類例項上呼叫父類方法的Method例項
* @param args 傳入到方法引數值的物件陣列
* @param methodProxy 使用它呼叫父類的方法
*/
@Override
public Object intercept(Object proxy, Method method, Object[] args,MethodProxy methodProxy) throws Throwable {
System.out.println(proxy.getClass());
System.out.println("== Log:開始執行操作,方法名:" + method.getName() + " ==");
Object result = methodProxy.invoke(target, args); // 執行原方法
System.out.println("== Log:操作執行完畢 ==");
return result;
}
}
測試
package springpro1;
import com.test.dao.UserDao;
import com.test.dao.impl.UserDaolmpl;
public class TestDemo2 {
public static void main(String[] args) {
UserDao ud = new UserDaolmpl();
new MyJDKProxy(ud).createProxy().save();
System.out.println("--------------------------------------------");
new LogCglibProxy().createProxyInstance(ud).save();
}
}