前言
AOP 也是 Spring 中一个较为重要的内容,相对于传统的 OOP 模式,AOP 有很多让人难以理解的地方,本篇文章将向大家介绍 AOP 的实现方法及其底层实现,内容包括:
- 初始 AOP
- AOP 的基本概念
- AOP(concepts)术语
- 动态代理
- 通知介绍(前置、后置、返回、异常、环绕)
- 基于注解的方式配置通知
一、什么是AOP
这个可以看我之前的文章:当我变成一个服务员和售货员教你一分钟了解并学废Spring AOP!!!
二、Spring框架的AOP的底层实现
Srping框架的AOP技术底层也是采用的代理技术,代理的方式提供了两种
基于JDK的动态代理
必须是面向接口的,只有实现了具体接口的类才能生成代理对象
基于CGLIB动态代理
- 对于没有实现了接口的类,也可以产生代理,产生这个类的子类的方式
- Spring的传统AOP中根据类是否实现接口,来采用不同的代理方式
- 如果实现类接口,使用JDK动态代理完成AOP
- 如果没有实现接口,采用CGLIB动态代理完成AOP
- 对于没有实现了接口的类,也可以产生代理,产生这个类的子类的方式
- Spring的传统AOP中根据类是否实现接口,来采用不同的代理方式
- 如果实现类接口,使用JDK动态代理完成AOP
- 如果没有实现接口,采用CGLIB动态代理完成AOP
基于Spring的AOP简单实现
注意一下,在讲解之前,说明一点:使用Spring AOP,要成功运行起代码,只用Spring提供给开发者的jar包是不够的,请额外上网下载两个jar包:
- aopalliance.jar
- aspectjweaver.jar
三、通过配置的方式实现aop通知效果
xml配置
<bean id="logger" class="com.ahpome.company.utils.Logger" />
<aop:config>
<aop:aspect id="loggerAspect" ref="logger">
<aop:pointcut id="loggerRef" expression="execution(* com.ahpome.company..*.*(..)) and !bean(logger)" />
<aop:around method="record" pointcut-ref="loggerRef" />
</aop:aspect>
</aop:config>
logger.java
public Object record(ProceedingJoinPoint pjp){
Log log = new Log();
try {
log.setOperator("admin");
String mname = pjp.getSignature().getName();
log.setOperName(mname);
Object[] args = pjp.getArgs();
log.setOperParams(Arrays.toString(args));
Object obj = pjp.proceed();
if(obj != null){
log.setResultMsg(obj.toString());
}else{
log.setResultMsg(null);
}
log.setOperResult("success");
System.out.println("1111");
return obj;
} catch (Throwable e) {
log.setOperResult("failure");
log.setResultMsg(e.getMessage());
} finally{
}
return null; 注意:这里如果是返回null即使你调用的时候返回是null,即使你的方法中含有返回值
}
}
JDK动态代理
接口
public interface UserService {
void save();
int select();
}
接口实现类
public class UserServiceImpl implements UserService {
@Override
public void save() {
System.out.println("保存用户信息成功");
}
@Override
public int select() {
System.out.println("查询用户信息成功");
return 10;
}
}
JDK动态代理工厂类
public class JdkProxyFactory implements InvocationHandler {
private Object target;
public JdkProxyFactory(Object target) {
this.target = target;
}
public Object getProxyObject() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("增强代码,添加日志功能");
return method.invoke(target, args);
}
}
测试JDK动态代理?
@Test
public void JdkProxyTest() {
UserService userService = new UserServiceImpl();
JdkProxyFactory jdkProxyFactory = new JdkProxyFactory(userService);
UserService proxy = (UserService) jdkProxyFactory.getProxyObject();
proxy.save();
System.out.println("=========================");
proxy.select();
}
总结
以上就是我对Java开发大型互联网架构Spring AOP实现原理之Spring AOP底层实现 问题及其优化总结。
文章到这里就结束了
小编这里总结一份spring AOP的思维导图,想了解的小伙伴可以添加vx小助手:xiehuangbao1123 领取
|