SpringAOP
优点:
- 解藕
- 更好的代码复用
如何使用
- 创建maven项目,导入依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.0.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.11.RELEASE</version>
</dependency>
</dependencies> 创建一个计算器接口,定义加减乘除方法
package org.csu.utils; public interface Cal { public int add(int num1,int num2); public int sub(int num1,int num2); public int mul(int num1,int num2); public int div(int num1,int num2); }创建接口的实现类方法
package org.csu.utils.impl; import org.csu.utils.Cal; public class CalImpl implements Cal { public int add(int num1, int num2) { System.out.println("add方法的参数是["+ num1+","+num2+"]"); int result = num1 + num2; System.out.println("add方法的结果是["+ result+"]"); return result; } public int sub(int num1, int num2) { System.out.println("sub方法的参数是["+ num1+","+num2+"]"); int result = num1 - num2; System.out.println("sub方法的结果是["+ result+"]"); return result; } public int mul(int num1, int num2) { System.out.println("mul方法的参数是["+ num1+","+num2+"]"); int result = num1 * num2; System.out.println("mul方法的结果是["+ result+"]"); return result; } public int div(int num1, int num2) { System.out.println("div方法的参数是["+ num1+","+num2+"]"); int result = num1 / num2; System.out.println("div方法的结果是["+ result+"]"); return result; } }
上述代码中,日志信息与业务逻辑的耦合度很高,不利于系统的维护,使用AOP可以优化。可以通过动态***来实现AOP
给业务逻辑找一个***,打印日志信息的工作交给***来做,这样的话业务代码就只需要关注自身的业务即可。
package org.csu.utils;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
public class MyInvokationHandler implements InvocationHandler {
//接受委托对象
private Object object = null;
//返回***对象
public Object bind(Object object){
this.object = object;
return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method.getName() + "的参数是"+ Arrays.toString(args));
Object result = method.invoke(this.object,args);
System.out.println(method.getName()+"的结果是"+result);
return result;
}
} 以上通过动态***的方法实现AOP的过程,复杂且不好理解。Spring对AOP进行了封装,可以用面向对象的方法来实现AOP。
Spring不用创建InvocationHandler,只需要创建一个切面对象,将所有的非业务代码放在切面对象中完成即可。Spring会根据切面类以及目标类生成一个***对象
package org.csu.utils.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
@Aspect
public class LoggerAspect {
@Before("execution(public int org.csu.utils.impl.CalImpl.*(..))")
public void before(JoinPoint joinPoint){
//获取方法名
String name = joinPoint.getSignature().getName();
//获取参数
String args = Arrays.toString(joinPoint.getArgs());
System.out.println(name +"的aop参数是"+args);
}
} 两个注解:
- @Aspect : 表明该类是切面类
- @Component :把该类的对象注入到IOC容器中
spring.xml中配置aop
<?xml version="1.0" encoding="UTF-8"?>
<!-- 最基本的命名空间定义和空间装载 -->
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 创建 SimpleDateFormat 实例并对这个实例进行实例化-->
<!-- 自动扫描-->
<context:component-scan base-package="org.csu"></context:component-scan>
<!--使得asect注解生效,为目标类自动生成***对象-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans> context:component-scan 将 org.csu包中所有类进行扫描,如果该类同时添加了 @Component,则将该类扫描到ioc容器中,让ioc管理他的对象
aop:aspectj-autoproxy 让spring结合切面类与目标类自动生成***对象
调用aop
package org.csu.utils.test;
import org.csu.utils.Cal;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test2 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-aop.xml");
//获取***对象
Cal proxy =(Cal) applicationContext.getBean("calImpl");
proxy.add(6,7);
}
} 
京公网安备 11010502036488号