Spring开发系列教程(11)——AOP之使用注解装配AOP
上一节我们讲解了使用AspectJ的注解并配合一个复杂的execution(* xxx.Xyz.*(..))语法来定义应该如何装配AOP。在实际项目中这种写法其实很少使用。假设你写了一个SecurityAspectAspect Component public class SecurityAspect { Before(execution(public * com.itranswarp.learnjava.service.*.*(..))) public void check() { if (SecurityContext.getCurrentUser() null) { throw new RuntimeException(check failed); } } }基本能实现无差别全覆盖即某个包下面的所有Bean的所有方法都会被这个check()方法拦截。还有的童鞋喜欢用方法名前缀进行拦截Around(execution(public * update*(..))) public Object doLogging(ProceedingJoinPoint pjp) throws Throwable { // 对update开头的方法切换数据源: String old setCurrentDataSource(master); Object retVal pjp.proceed(); restoreCurrentDataSource(old); return retVal; }这种非精准打击误伤面更大因为从方法前缀区分是否是数据库操作是非常不可取的。我们在使用AOP时要注意到虽然Spring容器可以把指定的方法通过AOP规则装配到指定的Bean的指定方法前后但是如果自动装配时因为不恰当的范围容易导致意想不到的结果即很多不需要AOP代理的Bean也被自动代理了并且后续新增的Bean如果不清楚现有的AOP装配规则容易被强迫装配。使用AOP时被装配的Bean最好自己能清清楚楚地知道自己被安排了。例如Spring提供的Transactional就是一个非常好的例子。如果我们自己写的Bean希望在一个数据库事务中被调用就标注上TransactionalComponent public class UserService { // 有事务: Transactional public User createUser(String name) { ... } // 无事务: public boolean isValidName(String name) { ... } // 有事务: Transactional public void updateUser(User user) { ... } }或者直接在class级别注解表示“所有public方法都被安排了”Component Transactional public class UserService { ... }通过Transactional某个方法是否启用了事务就一清二楚了。因此装配AOP的时候使用注解是最好的方式。我们以一个实际例子演示如何使用注解实现AOP装配。为了监控应用程序的性能我们定义一个性能监控的注解Target(METHOD) Retention(RUNTIME) public interface MetricTime { String value(); }在需要被监控的关键方法上标注该注解Component public class UserService { // 监控register()方法性能: MetricTime(register) public User register(String email, String password, String name) { ... } ... }然后我们定义MetricAspectAspect Component public class MetricAspect { Around(annotation(metricTime)) public Object metric(ProceedingJoinPoint joinPoint, MetricTime metricTime) throws Throwable { String name metricTime.value(); long start System.currentTimeMillis(); try { return joinPoint.proceed(); } finally { long t System.currentTimeMillis() - start; // 写入日志或发送至JMX: System.err.println([Metrics] name : t ms); } } }注意metric()方法标注了Around(annotation(metricTime))它的意思是符合条件的目标方法是带有MetricTime注解的方法因为metric()方法参数类型是MetricTime注意参数名是metricTime不是MetricTime我们通过它获取性能监控的名称。有了MetricTime注解再配合MetricAspect任何Bean只要方法标注了MetricTime注解就可以自动实现性能监控。运行代码输出结果如下Welcome, Bob! [Metrics] register: 16ms小结使用注解实现AOP需要先定义注解然后使用Around(annotation(name))实现装配使用注解既简单又能明确标识AOP装配是使用AOP推荐的方式。本文转载自廖雪峰老师的官方网站 liaoxuefeng.com 。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2446467.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!