AOP术语:【基于动态代理和cglib代理】
Target【目标类】:需要被代理的类。例如:UserService.
Joinpoint【连接点】:可能被拦截的方法。
Pointcut【切入点】:已经被增强的连接点。
Advice【通知/增强】:增强代码:例如:after方法和befor方法。
Weaving【织入】:把增强Advice应用到目标对象Target中,创建新的代理对象Proxy的过程。
Proxy【代理对象】
Aspect【切面】:切入点Pointcut和通知Advice的结合。
图解:
JDK动态代理实现AOP小案例:
目录结构:
目标结构实现:【UserService】
public interface UserService {
public void AddUser();
public void UpdateUser();
public void DeleteUser();
}
目标接口实现类:【UserServiceImpl】
public class UserServiceImpl implements UserService {
@Override
public void AddUser() {
System.out.println("添加成功");
}
@Override
public void UpdateUser() {
System.out.println("更新成功");
}
@Override
public void DeleteUser() {
System.out.println("删除成功");
}
}
通知类:【这里放的都是目标对象需要增强的方法们】
/**
*
* @author jishuai
* @category 切面类【Aspect】
*/
public class MyAspect {
public void Befor() {
System.out.println("开启事务");
}
public void After() {
System.out.println("结束事务");
}
}
切面类:【将切入点和通知结合】
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyBeanFactory {
public static UserService CreatUserService() {
// 创建目标类
UserService target = new UserServiceImpl();
//创建切面类
MyAspect myAspect = new MyAspect();
/**
* 生成代理类 将目标类和切面类结合 【这就是所谓的切面】
* loader:类加载器 一般采用:当前类名.class
* 也可采用:目标类的加载器->目标类名.getClass().getClassLoader();
* Class[] interfaces: 代理类需要实现的所有接口。方式一:目标类.getClass().getInterfaces(); 只能获得当前类的接口,不能获得父元素的接口
* 方式二:new Class[]{UserService.class}; 这个方式获得多个类的接口。
* InvocationHandler:处理类,接口,采用匿名内部类
*
*/
//代理对象
UserService userServiceProx = (UserService)Proxy.newProxyInstance(
target.getClass().getClassLoader(),
new Class[] {UserService.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行切面类的前方法
myAspect.Befor();
// 执行目标方法
Object obj = method.invoke(target, args);
myAspect.After();
//执行切面类的前方法
return obj;
}
});
return userServiceProx;
}
}
测试类:
import org.junit.Test;
public class MyTest {
@Test
public void f() {
UserService userService = MyBeanFactory.CreatUserService();
userService.AddUser();
System.out.println("-------------");
userService.UpdateUser();
System.out.println("-------------");
userService.DeleteUser();
}
}
执行结果:
CGLIB动态代理实现AOP小案例:
目录结构:
目标类:UserService
public class UserService {
public void AddUser() {
System.out.println("添加员工成功");
}
public void UpdateUser() {
System.out.println("更新员工成功");
}
public void DeleteUser() {
System.out.println("删除员工成功");
}
}
通知类:MyAspect
public class MyAspect {
public static void Befor() {
System.out.println("开始事务");
}
public static void After() {
System.out.println("结束事务");
}
}
切面类:【MyBeanFactory】将目标类和通知结合起来 实现MethodInterceptor接口 还得生成一个工具代理类
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 MyBeanFactory implements MethodInterceptor {
// 生成目标对象 聚合目标对象
private UserService target;
// 代理工厂构造函数
public MyBeanFactory(UserService target) {
this.target = target;
}
// 该方法返回代理对象
public Object createUserServiceProxy() {
// 创建一个工具类
Enhancer enhancer = new Enhancer();
// 设置父类
enhancer.setSuperclass(target.getClass());
// 设置回调函数
enhancer.setCallback(this);
// 创建子类对象,即代理对象
Object proxy = enhancer.create();
return proxy;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// 执行前方法
MyAspect.Befor();
// 执行目标对象方法
Object object = method.invoke(target, objects);
// 执行后方法
MyAspect.After();
return object;
}
}
测试类:
import org.junit.Test;
public class MyTest {
@Test
public void f() {
UserService userService = new UserService();
MyBeanFactory beanFactory = new MyBeanFactory(userService);
UserService userServiceProxy = (UserService)beanFactory.createUserServiceProxy();
userServiceProxy.AddUser();
System.out.println("---------");
userServiceProxy.UpdateUser();
System.out.println("---------");
userServiceProxy.DeleteUser();
}
}
执行结果: