概述:面向切面编程是通过预编译和运行期间动态代理实现程序功能统一维护的一种技术。
简单来说,就是把程序重复的代码抽取出来,在需要执行的时候使用动态代理技术,在不修改源代码的基础上,对我们已有的方法进行增强。
为什么要使用AOP:利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各个部分之间的耦合降低,提高程序的重用性,同时提高了开发的效率。
作用:在程序运行期间,不修改源码对已有的方法增强
优势:1.减少重复代码;2.提高开发效率;3.维护方便。
实现方式:JDK动态代理和cglib动态代理
优点:"业务类"只关注"业务逻辑",以保证重用性(代理的共有优点)
规模小:"代理对象"只受一种委托;如果"目标对象"很多,需一一代理,故不适用于大程序。
难扩展:若接口增一法,则实现类要改、代理类亦改。
使用cglib开源包,将代理对象的class文件加载进来,利用字节码技术修改class文件的字节码生成子类,进而实现代理类。
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>3.2.2</version>
</dependency>
//卖家类(类似于工商局),实现卖家接口,才具备卖车资格
public interface Seller {
void sell();
}
//汽车工厂(目标类)实现Seller接口,
public class AutoFactory implements Seller{
public void sell() {
System.out.println("卖新能源汽车");
}
}
/**
* 静态代理类(4S店)
* 目标:4S店使用静态代理,代理卖汽车厂家的车,实现收取买车前和买车后的管理费
*/
public class FourShop implements Seller {
private Seller realSeller; //实际卖车的人
public FourShop(Seller realSeller) {
this.realSeller = realSeller;
}
public void sell() {
System.out.println("4s店代理买车,收取管理费");
realSeller.sell();
System.out.println("4s店代理买车,收取返点");
}
//测试
public static void main(String[] args) {
Seller seller = new FourShop(new AutoFactory());
seller.sell();
}
}
import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * Cglib动态代理: * 代理类一本作为一个拦截器使用,实现MethodInterceptor接口,重写intercept方法,在方法中使用Method的形参调用invoke()方法,将目标类对象作为参数传递
* Enhancer:代码增强类 */ public class CglibProxy implements MethodInterceptor { private Seller realSell; public CglibProxy(Seller realSell) { this.realSell = realSell; }
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("CglibProxy收费--before");
method.invoke(realSell);
System.out.println("CglibProxy收费--after");
return null;
}
//测试
public static void main(String[] args) {
//Cglib动态代理,需用Enhancer增强类
Enhancer enhancer = new Enhancer();
//指定代理的类为汽车工厂
CglibProxy interceptor=new CglibProxy(new AutoFactory());
enhancer.setCallback(interceptor);
//设置超类
enhancer.setSuperclass(Seller.class);
//创建一个超类对象
Seller seller = (Seller)enhancer.create();
seller.sell();
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* JDK动态代理,实现InvocationHandler接口和重写invoke方法
*/
public class JDKProxy implements InvocationHandler {
private Seller realSeller;
public JDKProxy(Seller realSeller) {
this.realSeller = realSeller;
}
// InvocationHandler(请求处理者)
// invoke(...):核心方法——请求
// 集中处理 "动态代理类" 的所有方法调用
// 参数1:代理类的实例,类型如:class com.sun.proxy.$Proxy4
// 参数2:代理要执行的方法
// 参数3:方法的参数
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK动态代理前");
method.invoke(realSeller);
System.out.println("JDK动态代理后");
return null;
}
public static void main(String[] args) {
Seller realSeller=new AutoFactory();
// - 参数1:ClassLoader loader
ClassLoader classLoader = realSeller.getClass().getClassLoader();
// - 参数2:Class<?>[] interfaces【(被代理)接口数组(一个委托类可以实现多个接口)】
Class<?>[] interfaces = realSeller.getClass().getInterfaces();
// - 参数3:InvocationHandler jdkProxy
JDKProxy jdkProxy = new JDKProxy(realSeller);
Seller proxyInstance = (Seller)Proxy.newProxyInstance(classLoader, interfaces, jdkProxy);
proxyInstance.sell();
}
}
原文:https://www.cnblogs.com/jasonjson/p/12397704.html