Aop(面向切面编程)
使用注解的方式:
- 加入相应的jar包:
- com.springsource.org.aopalliance-1.0.0.jar
- com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
- sping-aspects-4.3.3.RELEASE.jar
创建一个切面类
package com.alibaba.wlq.invoke; import java.util.Arrays; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; //@Aspect:表示该类为切面类 @Aspect //@Component:表示该类由Spring管理 @Component public class logAspect { //@Before:表示before方法在被通知的程序类的方法执行之前执行 //execution():表示需要被通知的类中的add方法,add方法可以用通配符表示,那就表示该类中所有的方法都要被通知 @Before(value="execution(* com.alibaba.wlq.invoke.ArithmeticImp.add(double,double))") //JoinPoint:是程序执行中的一个精确执行点,例如类中的一个方法。它是一个抽象的概念,在实现AOP时,并不需要去定义一个join point public void before(JoinPoint joinpoint) { //获得被通知程序类的参数,返回类型是一个数组 Object[] args = joinpoint.getArgs(); //获取被通知程序类的方法名,返回类型是字符串 String name = joinpoint.getSignature().getName(); System.out.println("alibaba------>the method "+name+" begin with"+Arrays.asList(args)); } //@After:后置通知,表示在类的方法执行后、类中的return方法执行前执行 @After(value="execution(* com.alibaba.wlq.invoke.ArithmeticImp.add(double,double))") public void after() { System.out.println("alibaba------>the method *** end result"); } }
创建被通知的类的接口
package com.alibaba.wlq.invoke; public interface Arithmetic { public double add(double a,double b); }
创建被通知的类并且继承接口重写其中的方法
package com.alibaba.wlq.invoke; import org.springframework.stereotype.Component; @Component public class ArithmeticImp implements Arithmetic{ @Override public double add(double a, double b) { double result = a + b; System.out.println(result); return result; } }
配置文件中的配置
<?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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd"> <!-- 包扫描,前提加入aop的jar包 --> <context:component-scan base-package="com.alibaba.wlq"></context:component-scan> <!-- 开启切面注解 --> <aop:aspectj-autoproxy/> </beans>
测试类
package com.alibaba.wlq.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.alibaba.wlq.controller.UsersController; import com.alibaba.wlq.invoke.Arithmetic; import com.alibaba.wlq.invoke.ArithmeticImp; public class Test2 { public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext app = new ClassPathXmlApplicationContext("app3.xml"); Arithmetic arith = (Arithmetic) app.getBean("arithmeticImp"); arith.add(15.0, 20.0); } }
打印结果
alibaba------>the method add begin with[15.0, 20.0] 35.0 alibaba------>the method *** end result
- 加入相应的jar包:
使用xml配置文件
导入相应的jar包
创建接口并且创建相应的类实现该接口
package com.alibaba.wlq.invoke; public interface Metic { public double add(double a,double b); public double sub(double a,double b); public double mul(double a,double b); public double div(double a,double b); }
package com.alibaba.wlq.invoke; public class MeticImp implements Metic{ @Override public double add(double a, double b) { double result = a + b; System.out.println(result); return result; } @Override public double sub(double a, double b) { double result = a - b; System.out.println(result); return result; } @Override public double mul(double a, double b) { double result = a * b; System.out.println(result); return result; } @Override public double div(double a, double b) { double result = a / b; System.out.println(result); return result; } }
创建切面类
package com.alibaba.wlq.invoke; import java.util.Arrays; import org.aspectj.lang.JoinPoint; public class Invoke { public void before(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); String name = joinPoint.getSignature().getName(); System.out.println("alibaba------>the method "+name+" begin with "+Arrays.asList(args)); } public void after(JoinPoint joinPoint) { String name = joinPoint.getSignature().getName(); System.out.println("alibaba------>the method "+name+" end result:"); } public void afterreturn(Object result) { System.out.println("result:========"+result); } }
配置文件
<?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:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd"> <!-- 定义被通知的程序类 --> <bean id="metic" class="com.alibaba.wlq.invoke.MeticImp"></bean> <!-- 定义切面类的Bean --> <bean id="invoke" class="com.alibaba.wlq.invoke.Invoke"></bean> <!-- 配置切面 --> <aop:config> <!-- 定义表达式、切点 --> <aop:pointcut expression="execution(* com.alibaba.wlq.invoke.*.*(..))" id="point"/> <!-- 定义切面 --> <aop:aspect ref="invoke"> <!-- 定义前置通知 --> <aop:before method="before" pointcut-ref="point" /> <!-- 定义后置通知 --> <aop:after method="after" pointcut-ref="point"/> <!-- 定义返回通知returning属性值得名称要和方法中的参数名称一致 --> <aop:after-returning method="afterreturn" pointcut-ref="point" returning="result"/> </aop:aspect> </aop:config> </beans>
测试类
package Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.alibaba.wlq.invoke.Metic; public class Test1 { public static void main(String[] args) { ApplicationContext app = new ClassPathXmlApplicationContext("app.xml"); Metic arith = (Metic) app.getBean("metic"); arith.add(15, 10); } }
输出结果
alibaba------>the method add begin with [15.0, 10.0] 25.0 alibaba------>the method add end result: result:========25.0