01_AOP 概述
什么是 AOP
- 全称是 Aspect Oriented Programming 即: 面向切面编程。
- 简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技 术,在不修改源码的基础上,对我们的已有方法进行增强。
AOP 的作用及优势
-
作用:
在程序运行期间,不修改源码对已有方法进行增强。 -
优势:
减少重复代码
提高开发效率
维护方便
AOP 的实现方式
- 使用动态代理技术
AOP 的具体应用
- 需求:完成账户的增删改
以增加用户为例,在操作增加前,需要校验权限,操作增加后,需要进行日志记录。
1,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();
}
}
2,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("删除用户");
}
}
3,自定义Spring容器
存在问题
- 上面的代码,通过对业务层改造,已经可以实现在操作增加前,进行校验权限,操作增加 后,进行日志记录,也产生了一个新的问题:业务层方法变得臃肿了,里面充斥着很多重复 代码。
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; }
}