1.什么是AOP
2.AOP术语
程序流程图
3.AOP动态代理
3.1JDK动态代理
局限性:使用动态代理的对象
∗
∗
必
须
实
现
一
个
或
多
个
接
口
∗
∗
\color{red}{**必须实现一个或多个接口**}
∗∗必须实现一个或多个接口∗∗
UserDao接口
package com.lin.jdk;
public interface UserDao {
public void addUser();
public void deleteUser();
}
UserDaoImpl实现类
package com.lin.jdk;
//目标类
public class UserDaoImpl implements UserDao{
@Override
public void addUser() {
System.out.println("添加用户!");
}
@Override
public void deleteUser() {
// TODO Auto-generated method stub
System.out.println("删除用户!");
}
}
MyAspect切面类
package com.lin.aspect;
//切面类:可以存在多个通知Advice(既增强的方法)
public class MyAspect {
public void check_Permissions() {
System.out.println("模拟检查权限...");
}
public void log() {
System.out.println("模拟记录日志...");
}
}
JdkProxy类JDK的代理类 声明目标类接口
package com.lin.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.lin.aspect.MyAspect;
/**
* JDK的代理类 声明目标类接口
*
*/
public class JdkProxy implements InvocationHandler {
// 声明目标类接口
private UserDao userDao;
//创建代理方法
public Object createProxy(UserDao userDao) {
this.userDao=userDao;
//1.需要得到一个类加载器
ClassLoader classLoader= JdkProxy.class.getClassLoader();
//2.被代理对象实现所有接口
Class<?>[] clazz=userDao.getClass().getInterfaces();
//3.使用代理类进行增强,返回的是代理后的对象
return Proxy.newProxyInstance(classLoader, clazz, this);
}
/**
* 所有动态代理类的方法都会交由invoke()方法去处理
* proxy就是被代理后的对象
* method将要被执行的方法信息(反射过来的)
* args执行方法时需要的参数
*
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//声明切面
MyAspect myAspect=new MyAspect();
//前增强
myAspect.check_Permissions();
//在目标类上调用方法,并传入参数
Object obj=method.invoke(userDao, args);
//后增强
myAspect.log();
return obj;
}
}
测试类
package com.lin.jdk;
public class JdkTest {
public static void main(String[] args) {
//创建代理对象
JdkProxy jdkProxy = new JdkProxy();
//创建目标对象
UserDao userDao=new UserDaoImpl();
//从代理对象中获取增强后的目标对象
UserDao userDao1= (UserDao) jdkProxy.createProxy(userDao);
//执行方法
userDao1.addUser();
userDao1.deleteUser();
}
}
3.2CGLIB代理
1.创建UserDao类(不是接口)
package com.lin.cglib;
public class UserDao {
public void addUser() {
System.out.println("添加用户");
}
public void deleteUser() {
System.out.println("删除用户");
}
}
MyAspect切面类
package com.lin.aspect;
//切面类:可以存在多个通知Advice(既增强的方法)
public class MyAspect {
public void check_Permissions() {
System.out.println("模拟检查权限...");
}
public void log() {
System.out.println("模拟记录日志...");
}
}
创建 CglibProxy类
package com.lin.cglib;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import com.lin.aspect.MyAspect;
public class CglibProxy implements MethodInterceptor {
//代理方法
public Object createProxy(Object target) {
//创建一个动态类对象
//Enhancer是CGlib的核心类
Enhancer enhancer=new Enhancer();
//确定需要增强的类,设置其父类
enhancer.setSuperclass(target.getClass());
//添加回调函数 MethodInterceptor extends org.springframework.cglib.proxy.Callback
enhancer.setCallback(this);
//返回创建的代理类
return enhancer.create();
}
/**
* proxy:CGlib根据制定父类生成的代理对象
* method 拦截方法
* args :拦截的方法的参数数组
* methodProxy:方法的代理对象,用于执行父类的方法
*
*
*/
//intercept在程序执行目标方法时被调用
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
//创建切面对象
MyAspect myAspect=new MyAspect();
//前增强
myAspect.check_Permissions();
//目标方法执行
Object obj=methodProxy.invokeSuper(proxy, args);
//后增强
myAspect.log();
return obj;
}
}
测试类CglibTest
package com.lin.cglib;
public class CglibTest {
public static void main(String[] args) {
//创建代理对象
CglibProxy cglibProxy=new CglibProxy();
//创建目标对象
UserDao userDao=new UserDao();
//获取增强后的目标对象
UserDao userDao1= (UserDao) cglibProxy.createProxy(userDao);
//执行方法
userDao1.addUser();
userDao1.deleteUser();
}
}
运行结果:
和JDK动态代理一样