1、面向切面编程(AOP)的概念:把项目中需要在多处用到的功能,比如日志、安全和事物等集中到一个类中处理,而不用在每个需要用到该功能的地方显式调用。 2、术语解释: 横切关注点:分布应用于多处的功能 切面:横切关注点可以被模块化为一个类,这个类被称为一个切面 通知(advice):切面要完成的工作。SPRing的通知有5种类型:before、after、after-returning、after-throwing和around这五种类型。 连接点(joinpoint):连接点表示在何种操作发生时应用切面。比如方法调用时、修改字段时和抛出异常时等等 切点(pointcut):一般用某个包中的类的明确的方法来指定在何处应用切面,应用切面的这个点便称为切点,一般用切点来指定连接点。
第一步:导入jar包(Spring与aspectJ) 第二步:Spring的主配置文件: i.在表头中添加aop、context的命名空间
<?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.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">第三歩:在配置文件中开启aop注解
<aop:aspectj-autoproxy proxy-target-class="true"/>第四步:让类生产bean对象,通过扫描包,所有注解的类都生产bean
<context:component-scan base-package="com.iotek.aspect"/>第五步: 定义横切面类
package com.iotek.aspect;import java.util.Arrays;import java.util.List;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;@Component("logAspect")public class LogAspect { /* * 1、@Before:在某个方法执行前调用 * 2、@After:在某个方法执行后调用 * 3、@AfterReturning:在某个方法执行后调用,且获得其返回值 * 4、@AfterThrowing:在某个方法执行后调用,如果有异常在执行此方法 * 5、@Around:环绕执行,包含了@Before与@After等(不常用) * * 注意:执行参数的设置 * 例如:@Before("execution(public void com.iotek.daoImpl.ComputeDaoImpl.add(int, int))") * execution(---):执行命令 * 简化:@Before("execution(* com.iotek.daoImpl.ComputeDaoImpl.*(..))") * * * 常用的对象: * JoinPoint:获得信息: * 1、获得当前执行的方法名: * 2、获得方法中参数传递的内容 * */ /* * 由于每个方法执行的内容都相同:execution(内容都相同) * 则将内容提起出来 PointCut */ /*@Pointcut(value="execution(* com.iotek.daoImpl.ComputeDaoImpl.*(..))") public void qrd(){};*/ //--设置方法执行点: //@Before("execution(public void com.iotek.daoImpl.ComputeDaoImpl.add(int, int))") //@Before("execution(* com.iotek.daoImpl.ComputeDaoImpl.*(..))") //@Before("qrd()") /* * */ public void xmlBefore(JoinPoint point){ String name=point.getSignature().getName(); List list=Arrays.asList(point.getArgs()); System.out.println("--->xmlBefore名字是:"+name+"参数是:"+list); } public void xmlAfter(){ System.out.println("--->xmlAfter名字是"); } public void afterException(JoinPoint point,Exception ex){ String methodName = point.getSignature().getName(); System.out.println("--->afterException"+methodName+":异常信息:"+ex); } public void afterReturnMethod(JoinPoint point,Object res){ String methodName=point.getSignature().getName(); System.out.println("--->afterResultMethod方法名称是:"+methodName+"-返回值:"+res); } public void aroundMethod(JoinPoint point){ String methodName=point.getSignature().getName(); List list=Arrays.asList(point.getArgs()); System.out.println("--->aroundMethod:"+methodName+"-参数:"+list); }}第六步、定义实体类
package com.iotek.dao;public class PersonDao { public void add(int i, int j) { int sum = i /j; System.out.println("add==="+sum); } public int sum(int i, int j) { int sum = i + j; System.out.println("sum==="+sum); return sum; }}第七步、注册AOP对象
<!-- 注册:AOP对象 --> <bean id="logAspect" class="com.iotek.aspect.LogAspect"></bean>第八步、 定义切入点 表达式:PointCut
<!-- 定义切入点 表达式:PointCut --> <aop:pointcut expression="execution(* com.iotek.dao.PersonDao.*(..))" id="log"/> <aop:aspect ref="logAspect"> <aop:before method="xmlBefore" pointcut-ref="log"/> <aop:after method="xmlAfter" pointcut-ref="log"/> <aop:after method="aroundMethod" pointcut-ref="log"/> <aop:after-returning method="afterReturnMethod" returning="res" pointcut-ref="log"/> <aop:after-throwing method="afterException" throwing="ex" pointcut-ref="log"/> </aop:aspect> </aop:config>第九步、测试类
package com.iotek.demo;import org.springframework.context.applicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.iotek.dao.PersonDao;public class Demo { public static void main(String args[]){ ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml"); PersonDao person=context.getBean("person", PersonDao.class); person.add(10, 5); person.sum(2, 1); }}applicationContext.xml的完整配置
<?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.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> <aop:aspectj-autoproxy proxy-target-class="true"/> <context:component-scan base-package="com.iotek.aspect"/> <bean id="person" class="com.iotek.dao.PersonDao"></bean> <aop:config> <!-- 定义切入点 表达式:PointCut --> <aop:pointcut expression="execution(* com.iotek.dao.PersonDao.*(..))" id="log"/> <aop:aspect ref="logAspect"> <aop:before method="xmlBefore" pointcut-ref="log"/> <aop:after method="xmlAfter" pointcut-ref="log"/> <aop:after method="aroundMethod" pointcut-ref="log"/> <aop:after-returning method="afterReturnMethod" returning="res" pointcut-ref="log"/> <aop:after-throwing method="afterException" throwing="ex" pointcut-ref="log"/> </aop:aspect> </aop:config> </beans>通过扫描包完成Bean的注入,需要在类中声明@Component(“logAspect”) 切面类也可以通过注解方式定义:
package com.iotek.aspect2;import java.util.Arrays;import java.util.List;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;@Aspectpublic class LogAspect2 { @Before("execution(* com.iotek.dao.PersonDao.*(..))") public void xmlBefore(JoinPoint point){ String name=point.getSignature().getName(); List list=Arrays.asList(point.getArgs()); System.out.println("--->xmlBefore名字是22222222:"+name+"参数是:"+list); } @After("execution(* com.iotek.dao.PersonDao.*(..))") public void xmlAfter(){ System.out.println("--->xmlAfter名字是2222222"); } @AfterThrowing(value="execution(* com.iotek.dao.PersonDao.*(..))",throwing="ex") public void afterException(JoinPoint point,Exception ex){ String methodName = point.getSignature().getName(); System.out.println("--->afterException222222"+methodName+":异常信息:"+ex); } @AfterReturning(value="execution(* com.iotek.dao.PersonDao.*(..))",returning="res") public void afterReturnMethod(JoinPoint point,Object res){ String methodName=point.getSignature().getName(); System.out.println("--->afterResultMethod方法名称是22222222222:"+methodName+"-返回值:"+res); }}新闻热点
疑难解答