一、作用
作用:在不修改源代码的情况下,可以实现功能的增强。
aop思想:基于代理思想,对原来目标对象,创建代理对象,在不修改原对象代码情况下,通过代理对象,调用增强功能的代码,从而对原有业务方法进行增强 !
二、应用场景
场景一: 记录日志
场景二: 监控方法运行时间 (监控性能)
场景三: 权限控制
场景四: 缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )
场景五: 事务管理 (调用方法前开启事务, 调用方法后提交关闭事务 )
三、SpringAOP应用示例
依赖maven坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
业务类
public class Hello {
public void sayHello() throws Exception {
System.out.println("hello...");
// throw new Exception();
}
}
切面类
@Aspect
public class LogAspects {
@Before("execution(* aop.spring.Hello.sayHello(..))")
public void before(){
System.out.println("before..........");
}
@After("execution(* aop.spring.Hello.*(..))")
public void after(){
System.out.println("after..........");
}
@AfterReturning("execution(* aop.spring.Hello.*(..))")
public void afterReturning(){
System.out.println("afterReturning..........");
}
@AfterThrowing("execution(* aop.spring.Hello.*(..))")
public void afterThrowing(){
System.out.println("afterThrowing..........");
}
// @Around("execution(* aop.spring.Hello.sayHello(..))")
public void around(){
System.out.println("around..........");
}
}
spring配置类
@EnableAspectJAutoProxy
@Configuration
public class SpringConfig {
// 业务类
@Bean
public Hello hello(){
return new Hello();
}
// 切面类
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
测试类
public class TestSpringAop {
@Test
public void test1() throws Exception {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
Hello hello = annotationConfigApplicationContext.getBean(Hello.class);
hello.sayHello();
}
}
四、AOP实现原理
1、JDK动态代理
2、Cglib动态代理
五、静态代理
依赖坐标
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
业务接口类
public interface IHello {
void sayHello();
}
业务实现类
public class HelloImpl implements IHello {
@Override
public void sayHello() {
System.out.println("hello...");
}
}
代理类
public class HelloProxy implements IHello{
private IHello hello; // 业务类
public HelloProxy(IHello hello){
// 传入具体哪个业务类
this.hello = hello;
}
@Override
public void sayHello() {
System.out.println("记录日志");
this.hello.sayHello();
}
}
测试类
public class TestStaticProxy {
@Test
public void test1(){
HelloProxy helloProxy = new HelloProxy(new HelloImpl());
helloProxy.sayHello();
}
}
六、JDK动态代理
依赖坐标
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
业务接口类
public interface UserDao {
void saveUser();
}
业务实现类
public class UserDaoImpl implements UserDao {
@Override
public void saveUser() {
System.out.println("持久层:用户保存");
}
}
代理类
public class JdkProxy implements InvocationHandler {
private Object target; // 业务类
public JdkProxy(Object target){
// 传入具体哪个业务类
this.target = target;
}
public Object getProxy(){
// 获取代理类
Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
return proxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("记录日志");
Object result = method.invoke(target, args); //被代理的类执行方法
return result;
}
}
测试类
public class TestJdk {
@Test
public void test(){
final UserDao userDao = new UserDaoImpl();
UserDao proxy = (UserDao)new JdkProxy(userDao).getProxy();
proxy.saveUser();
}
}
七、Cglib动态代理
业务类
public class LinkManDao {
public void save(){
System.out.println("持久层:联系人保存....");
}
}
代理类
public class CGLibProxy implements MethodInterceptor {
private Object target; // 业务类
public CGLibProxy(Object target){
// 传入具体哪个业务类
this.target = target;
}
public Object getProxy(){
// 获取代理类
Object proxy = Enhancer.create(target.getClass(), this);
return proxy;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("记录日志");
Object result = methodProxy.invokeSuper(o, objects);
return result;
}
}
测试类
public class TestCglib {
@Test
public void test3(){
final LinkManDao linkManDao = new LinkManDao();
LinkManDao proxy = (LinkManDao)new CGLibProxy(linkManDao).getProxy();
proxy.save();
}
}