AOP (Aspect Oriented Programing) :面向切面編程,它是一種編程思想。AOP采取橫向抽取機(jī)制,取代了傳統(tǒng)縱向繼承體系重復(fù)性代碼的編寫方式(可用于性能監(jiān)視、事務(wù)管理、安全檢查、緩存,日志記錄等)。
AOP就是要對(duì)目標(biāo)進(jìn)行代理對(duì)象的創(chuàng)建,Spring AOP是基于動(dòng)態(tài)代理的,基于兩種動(dòng)態(tài)代理機(jī)制:JDK動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理。
動(dòng)態(tài)代理和靜態(tài)代理區(qū)別?
動(dòng)態(tài)代理:在虛擬機(jī)內(nèi)部,運(yùn)行的時(shí)候,動(dòng)態(tài)生成代理類(運(yùn)行時(shí)生成,runtime生成) ,并不是真正存在的類, Proxy$$ (Proxy$$User)
靜態(tài)代理:存在代理類 (例如:struts2 Action的代理類 ActionProxy)
JDK代理:基于接口的代理,一定是基于接口,會(huì)生成目標(biāo)對(duì)象的接口類型的子對(duì)象。
Cglib代理:基于類的代理,不需要基于接口,會(huì)生成目標(biāo)對(duì)象類型的子對(duì)象。
JDK動(dòng)態(tài)代理
接口
public interface UserService {
void save();
int select();
}
接口實(shí)現(xiàn)類
public class UserServiceImpl implements UserService {
@Override
public void save() {
System.out.println("保存用戶信息成功");
}
@Override
public int select() {
System.out.println("查詢用戶信息成功");
return 10;
}
}
JDK動(dòng)態(tài)代理工廠類
public class JdkProxyFactory implements InvocationHandler {
private Object target;
public JdkProxyFactory(Object target) {
this.target = target;
}
/**
* 獲取代理對(duì)象,當(dāng)前類繼承InvocationHandler
*
* @return
*/
public Object getProxyObject() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//添加功能
System.out.println("增強(qiáng)代碼,添加日志功能");
//執(zhí)行原有方法
return method.invoke(target, args);
}
}
測(cè)試JDK動(dòng)態(tài)代理
@Test
public void JdkProxyTest() {
//創(chuàng)建目標(biāo)對(duì)象
UserService userService = new UserServiceImpl();
//創(chuàng)建工廠對(duì)象
JdkProxyFactory jdkProxyFactory = new JdkProxyFactory(userService);
UserService proxy = (UserService) jdkProxyFactory.getProxyObject();
proxy.save();
System.out.println("=========================");
proxy.select();
}
CGLIB動(dòng)態(tài)代理
需生成代理對(duì)象的類
public class OrderService {
public void save() {
System.out.println("保存訂單成功");
}
public int select() {
System.out.println("查詢訂單成功");
return 10;
}
}
CGLIB動(dòng)態(tài)代理工廠類
public class CglibProxyFactory implements MethodInterceptor {
private Object target;
public CglibProxyFactory(Object target) {
this.target = target;
}
/**
* 獲取代理對(duì)象
*
* @return
*/
public Object getProxyObject() {
Enhancer enhancer = new Enhancer();
//設(shè)置兩個(gè)參數(shù)
//設(shè)置生成代理類的目標(biāo)對(duì)象(代理類對(duì)象是目標(biāo)對(duì)象的子類)
enhancer.setSuperclass(target.getClass());
//設(shè)置回調(diào)方法
enhancer.setCallback(this);
//生成代理對(duì)象
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//添加功能
System.out.println("增強(qiáng)代碼,添加日志功能");
//執(zhí)行原有方法
return method.invoke(target, objects);
}
}
測(cè)試CGLIB動(dòng)態(tài)代理
@Test
public void CglibProxyTest() {
//創(chuàng)建目標(biāo)對(duì)象
OrderService orderService = new OrderService();
//創(chuàng)建工廠對(duì)象
CglibProxyFactory cglibProxyFactory = new CglibProxyFactory(orderService);
OrderService proxy = (OrderService) cglibProxyFactory.getProxyObject();
proxy.save();
System.out.println("=========================");
proxy.select();
}