系统功能是公共的,在很多地方都会出现的功能,例如打印日志,性能监控,事务管理,安全验证等等,把需要某个系统的功能的方法看成一个切面。 典型的场景比如“开启事务,数据处理,提交事务”。这些重复的代码大多是所谓的权限管理、日志登陆、事务管理等必需却又污染着业务逻辑代码的内容,我们自然希望将它们提取出来,还业务逻辑一个清新的世界。
连接点joinpoint:需要加入功能的位置 切入点pointcut:执行加入功能的连接点 通知advice:需要实现的功能 切面aspect:java中将切入点和通知等组合在一起的代码单元 Target:要操作的对象 织入weave:将功能加入到切入点的过程
1)编写一个service类 2)编写一个通知类,实现MethodBeforeAdvice接口(三个参数,method方法,args方法的参数,target所在方法的对象) 3)配置切点 配置属性service的方法 4)配置切面
前置通知:methodbeforeadvice在方法前 后置通知:afterRunning advice在方法后 环绕通知:methodInterceptor 异常通知:ThrowsAdvice在出现异常时 最终通知:在finally执行时 after
需要在pom.xml加入aspectjweave依赖
public class Internal implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { Object[] args = methodInvocation.getArguments(); if(!Arrays.asList(args).contains("abc123")){ System.out.println("非法合法"+methodInvocation.getMethod().getName()); return null; }else{ System.out.println("参数合法"); } System.out.println(methodInvocation.getStaticPart()); return "你好" ; } } //对象 <bean id="springsop" class="com.woniu.spring.dao.springsop"/> //定义通知 <bean id="Internal" class="com.woniu.spring.aop.Internal"/> //定义切入点 <bean id="pointCut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="pattern" value="com.woniu.spring.dao.springsop.prints"></property> //给pattern属性赋值 </bean> //组合切面 <bean id="aspect" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="pointcut" ref="pointCut" /> <property name="advice" ref="Internal"/> </bean> //包装 <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>以上传统配置xml太过于繁琐下面介绍一个较为简单的方法
<!--对象--> <bean id="springsop" class="com.woniu.spring.dao.springsop"/> <!--通知--> <bean id="txAdvice" class="com.woniu.spring.aop.TransactionArtive"/> <aop:config> <aop:aspect ref="txAdvice"> <!--切入点--> <aop:pointcut id="daoPointCut" expression="execution(* com.woniu.spring.dao.*.*(..))"/> <!--通知--> <!--开始--> <aop:before method="start" pointcut-ref="daoPointCut"/> <!--正常--> <aop:after-returning method="commit" pointcut-ref="daoPointCut"/> <!--回滚--><aop:after-throwing method="rollback" pointcut-ref="daoPointCut"/> </aop:aspect> </aop:config>以上用aop标签需要用到上文所说的依赖,所以必须在有依赖的情况下才能使用 还是过于繁琐怎么办?当然有更好的办法上一篇文章中提到过用java注解配置IOC,那么我们是不是也可以用java注解的方式,请看下一段代码
@Aspect @Component public class Tswin { @Pointcut("execution(* com.woniu.spring.dao.*.*(..))") public void userDao() { } @Around("userDao()") public Object invoke(ProceedingJoinPoint pjp) { Object[] args = pjp.getArgs(); Object result = null; try { System.out.println("开启。。。"); result = pjp.proceed(args); System.out.println("结束。。。。"); } catch (Throwable throwable) { throwable.printStackTrace(); System.out.println("回滚。。。"); } return result; } }这时就是通过注解来配置而xml只需要
<context:component-scan base-package="com.woniu.spring"/> <aop:aspectj-autoproxy/>这么简简单单二句就可以了 这还不是最简单的,接下来说下最简单的纯java配置
@Configuration @ComponentScan("com.woniu.spring") @EnableAspectJAutoProxy public class Demi { }接下来就给类方法这些加上注解即可,会自动扫描到@Aspect 切面并应用
@EnableAspectJAutoProxy == aop:aspectj-autoproxy这两句话作用是一样的 @Pointcut切入点 execution(* com.woniu.spring.dao..(…))" 也要填入这句话 @Around通知 @Aspect声明切面
