AOP(Aspect Oriented Programming 面向切面编程)是一种指在程序运行期间动态的将某段代码切入到指定方法的指定位置进行运行的编程方式,这种编程方式实现了代码复用,是对传统OOP(Object Oriented Programming,面向对象编程 )的补充。目前,Aspectj是Java社区里最完整最流行的AOP框架,在Spring 2.0以上版本中可以通过Aspectj注解或基于XML配置AOP。
1、在pom.xml中进行maven配置,添加jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.6.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
2、Spring配置文件application.xml中添加<aop:aspectj-autoproxy/>
<!--找到切片类即由@Aspect注解的类,对其中切入点表达式中匹配的类生成代理类-->
<!--proxy-target-class默认是false,则由JDK自动生成代理类;若为true,则由CGLIB生成代理类-->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
3、自定义一个@Aspect修饰的切面类——>将其创建的对象保存于Spring IOC容器——>自定义增强方法,增强方法也称为通知方法,指有@Before、@AfterRunning、@AfterThrowing、@After或@Around注解修饰的Java方法。
package com.jd.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class CalculatorAspect {
@Pointcut("execution(public int com.jd.calculator.service.CalculatorService.*(..))")
//切入点表达式:用于指定执行哪些类中的哪些方法时触发增强方法,
public void pointcut(){
}
@Before("pointcut()")
public void before(JoinPoint jp){
Object [] args = jp.getArgs();
String name = jp.getSignature().getName();
System.out.println("The "+name+" method begins");
System.out.println("The parameters of the "+name+" method are "+args[0]+","+args[1]);
}
@After("pointcut()")
public void after(JoinPoint jp){
String name = jp.getSignature().getName();
System.out.println("The "+name+" method ends");
}
@AfterReturning(value="pointcut()",returning = "obj")
public void afterReturning(JoinPoint jp,Object obj){
String name = jp.getSignature().getName();
System.out.println("The "+name+" method result:"+obj);
}
@AfterThrowing(value="pointcut()",throwing = "e")
public void afterThrowing(JoinPoint jp,Throwable e){ //Throwable是所有异常类的父类
System.out.println("##########"+e.getMessage());
}
/*@Around("pointcut()") //可替代以上四种注解
public Object around(ProceedingJoinPoint jp){
try {
String name = jp.getSignature().getName();
Object result = null;
try {
Object [] args = jp.getArgs();
System.out.println("The "+name+" method begins");
System.out.println("The parameters of the "+name+" method are "+args[0]+","+args[1]);//@Before注解所修饰的方法
result = jp.proceed();//执行目标对象内的方法
} finally {
System.out.println("The "+name+" method ends");//@After注解所修饰的方法
}
System.out.println("The "+name+" method result:"+result);//@AfterReturning注解所修饰的方法
return result;
} catch (Throwable e) {
System.out.println("##########"+e.getMessage());//@AfterThrowing注解所修饰的方法
}
return -1;
}*/
}
4、去掉CalculatorService类中方法内输出语句,如下代码:
package com.jd.calculator.service;
import org.springframework.stereotype.Service;
@Service
public class CalculatorService implements ICalculatorService{
@Override
public int add(int a, int b) {
int retult = a+b;
return retult;
}
@Override
public int div(int a, int b) {
int retult = a/b;
return retult;
}
@Override
public int mul(int a, int b) {
int retult = a*b;
return retult;
}
}
5、编写测试代码,代码如下:
import com.jd.calculator.service.ICalculatorService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
ICalculatorService calculatorService = applicationContext.getBean(ICalculatorService.class);
//<aop:aspectj-autoproxy></aop:aspectj-autoproxy> proxy-target-class默认为false JDK:代理类是目标类接口的实现类
System.out.println(calculatorService.getClass().getName());//com.sun.proxy.$Proxy8
System.out.println(calculatorService.getClass().getInterfaces()[0].getName());//com.jd.calculator.service.ICalculatorService
//变量calculatorService指向代理类$Proxy8创建的对象,而代理类$Proxy8又实现了ICalculatorService类
calculatorService.add(1,2);//调用由$Proxy8类创建的对象中的add方法
applicationContext.close();
}
}
执行过程:
try {
try {
doBefore();// @Before注解所修饰的方法
method.invoke();// 执行目标对象内的方法
} finally {
doAfter();// @After注解所修饰的方法
}
doAfterReturning();// @AfterReturning注解所修饰的方法
} catch (Exception e) {
doAfterThrowing();// @AfterThrowing注解所修饰的方法
}
本文介绍了Spring AOP的概念,强调了其在代码复用中的作用。通过添加AspectJ相关依赖,配置Spring的aop:aspectj-autoproxy,创建@Aspect切面类并定义通知方法,实现面向切面的编程。测试代码验证了AOP的执行过程。
3716

被折叠的 条评论
为什么被折叠?



