01_AOP 概述
什么是 AOP
-
全称是 Aspect Oriented Programming 即: 面向切面编程。
-
简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改源码的基础上,对我们的已有方法进行增强。
AOP 的作用及优势
作用:
- 在程序运行期间,不修改源码对已有方法进行增强。
优势:
-
减少重复代码
-
提高开发效率
-
维护方便
AOP 的实现方式
- 使用动态代理技术
AOP 的具体应用
- 需求:完成账户的增删改
以增加用户为例,在操作增加前,需要校验权限,操作增加后,需要进行日志记录。
- service层
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
MyApplicationContext applicationContext = new
MyApplicationContext("myspring.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.addUser();
}
@Override
public void updateUser() {
MyApplicationContext applicationContext = new
MyApplicationContext("myspring.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.updateUser();
}
@Override
public void deleteUser() {
MyApplicationContext applicationContext = new
MyApplicationContext("myspring.xml");
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.deleteUser();
}
}
- dao层
public class UserDaoImpl implements UserDao {
@Override
public void addUser() {
System.out.println("添加用户");
}
@Override
public void updateUser() {
System.out.println("修改用户");
}
@Override
public void deleteUser() {
System.out.println("删除用户");
}
}
- 自定义Spring容器
- 参考"01-耦合性/03_之前三层架构中存在的耦合性问题及解决方案"
存在问题
- 上面的代码,通过对业务层改造,已经可以实现在操作增加前,进行校验权限,操作增加后,进行日志记录,也产生了一个新的问题:业务层方法变得臃肿了,里面充斥着很多重复代码。
02_动态代理
字节码随用随创建,随用随加载。
动态代理两种方式
- JDK 官方的 Proxy 类
-
基于接口的动态代理技术
-
被代理类最少实现一个接口
- 第三方的 CGLib
-
基于父类的动态代理技术
-
如果报 asmxxxx 异常,需要导入 asm.jar
-
被代理类不能用 final 修饰的类
03_动态代理之Proxy 类
JDK 官方的 Proxy 类
- 使用Proxy类改造getBean方法
public class MyApplicationContext {
......
public Object getBean(String id){
Object obj = map.get(id);
if (id.endsWith("Service")) {
Object enhanceObj =
Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("权限校验");
Object returnValue = method.invoke(obj, args);
System.out.println("日志记录");
return returnValue;
}
});
return enhanceObj;
}
return obj;
}
}
04_动态代理之Enhancer 类
CGLib 的 Enhancer 类
-
使用Enhancer类改造getBean方法
-
cglib属于spring-core.jar中的组件,所以需要导入spring环境
public class MyApplicationContext {
......
public Object getBean(String id){
Object obj = map.get(id);
if (id.endsWith("Service")) {
Object enhanceObj = Enhancer.create(obj.getClass(), new
InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects)
throws Throwable {
System.out.println("权限校验");
Object returnValue = method.invoke(obj, objects);
System.out.println("日志记录");
return returnValue;
}
});
return enhanceObj;
}
return obj;
}
}