[002]一步一步学懂spring - AOP和自定义注解
2017-07-18 09:14
267 查看
Spring有两大核心功能,一个是IOC,一个是AOP。IOC对于开发者来讲可能用的还比较多,声明一个bean交给spring容器来管理,或者从spring容器中找到某个bean注入到某一个bean中。而对于AOP来讲,普通开发者用的就不是很多了。往往是项目的整体架构都已经对切面进行处理完毕了,记录日志也好,处理数据库事务也好等等这些功能,程序员一般是不需要关注的,当然这也是AOP的核心--关注点分离。这篇笔记并不是来记录如何使用AOP的,对于AOP的讲解网络上有很多的文章,可以参考。这里主要介绍的是使用spring的Java配置的方式实现AOP,以及使用自定义注解。
用一个实际的例子来演示使用注解和使用单纯的AOP的方式来面向切面编程。我们这里需要一个注解类,两个服务提供者,一个切面,再加一个配置类和一个运行的类,运行的类并充当服务的消费者。
注解类
这里定义了一个注解,表示是运行时生效,目标是标注在方法上。可以指定一个name属性。注解本身就是一个标记,是没有任何的功能的。
第一个服务的提供者,不使用注解
这里就提供了一个空的add方法
第二个服务的提供者,使用注解
这里和第一个服务的提供者类似,同样提供了一个空的add方法,只是在add方法上标注了我们定义的action注解,并指定了name属性的值
切面
这个是我们的核心代码,先看注解,这里用到了Aspect,Component,Pointcut,Before,After。分别介绍这5个注解
了解了注解的基本功能之后,再来对代码进行分析。如果对AOP不熟悉的小伙伴可以先了解一下AOP的相关内容,再来继续向下看。这里其实就是两个通知,一个前置通知,一个后置通知,分别对应这两个切入点。切入点的配置方式有两种,第一种就是在前置通知中定义的形式,直接将切面表达式写到注解中,另外可以单独将切入点定义处理,并使用Pointcut来声明这个切入点表达式,方法的名字就是切点的名称。后置通知中就是使用的这种形式,在后置通知的注解中指定切点的方法名,这里一定要把方法的()加上,否则找不到切点。切点表达式定义的都非常简单,annotationPointCut()切点就是要切带有com.hy.spring.test3.Action这个注解的所有类, @Before("execution(*
com.hy.spring.test3.DemoService.*(..))")要切的就是com.hy.spring.test3.DemoService这个包下的所有类。下面我们再来看切了之后干的啥事,不难发现,做的事情也是非常的简单,带有注解的就是打印了注解中配置的值,没有注解的就打印了方法的名字。
配置类
ComponentScan是要扫描的包,这个注解会自动扫描指定包下的所有的类
EnableAspectJAutoProxy是开启切面的自动代理
测试类
这里只演示了注解的切面,非注解的同样。
用一个实际的例子来演示使用注解和使用单纯的AOP的方式来面向切面编程。我们这里需要一个注解类,两个服务提供者,一个切面,再加一个配置类和一个运行的类,运行的类并充当服务的消费者。
注解类
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Action { String name(); }
这里定义了一个注解,表示是运行时生效,目标是标注在方法上。可以指定一个name属性。注解本身就是一个标记,是没有任何的功能的。
第一个服务的提供者,不使用注解
@Service public class DemoService { public void add() { } }
这里就提供了一个空的add方法
第二个服务的提供者,使用注解
@Service public class DemoAnnotationService { @Action(name="注解拦截的add操作") public void add() { } }
这里和第一个服务的提供者类似,同样提供了一个空的add方法,只是在add方法上标注了我们定义的action注解,并指定了name属性的值
切面
@Aspect @Component public class LogAspect { @Pointcut("@annotation(com.hy.spring.test3.Action)") public void annotationPointCut() {} @Before("execution(* com.hy.spring.test3.DemoService.*(..))") public void begin(JoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); System.out.println("方法规则式拦截 " + method.getName()); } @After("annotationPointCut()") public void after (JoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); Action action = method.getAnnotation(Action.class); System.out.println("注解式拦截 " + action.name()); } }
这个是我们的核心代码,先看注解,这里用到了Aspect,Component,Pointcut,Before,After。分别介绍这5个注解
Aspect | 声明一个切面 |
Pointcut | 声明切点 |
Before | 声明前置通知 |
After | 声明后置通知 |
Component | 交给spring容器来管理 |
com.hy.spring.test3.DemoService.*(..))")要切的就是com.hy.spring.test3.DemoService这个包下的所有类。下面我们再来看切了之后干的啥事,不难发现,做的事情也是非常的简单,带有注解的就是打印了注解中配置的值,没有注解的就打印了方法的名字。
配置类
@Configuration @ComponentScan(value= "com.hy.spring.test3") @EnableAspectJAutoProxy public class AopConfig { }
ComponentScan是要扫描的包,这个注解会自动扫描指定包下的所有的类
EnableAspectJAutoProxy是开启切面的自动代理
测试类
public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class); DemoAnnotationService service = context.getBean(DemoAnnotationService.class); service.add(); context.close(); } }
这里只演示了注解的切面,非注解的同样。
相关文章推荐
- 利用Spring AOP自定义注解解决日志和签名校验 详解
- Spring+SpringMVC+Mybatis 利用AOP自定义注解实现可配置日志快照记录
- ######【spring属性注入(Ioc的DI)总结】:注解方式属性注入,属性名任意.=for理解:Aop注入代理对象时,注入被增强类对象时,属性名为proxy(自定义)。
- Spring AOP自定义注解 身份验证
- SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- Spring+SpringMVC+Mybatis 利用AOP自定义注解实现可配置日志快照记录
- Spring AOP实现复杂的日志记录(自定义注解)
- SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- spring AOP自定义注解方式实现日志管理
- spring AOP自定义注解方式实现日志管理 详解
- SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- SpringAOP实现自定义注解
- 使用Spring AOP和自定义注解记录日志
- 使用Spring AOP结合自定义Java注解实现动态数据源设置
- 利用Spring AOP处理自定义注解
- SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- spring aop实现的2种方式,以及自定义注解
- SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
- Spring+SpringMVC+Mybatis 利用AOP自定义注解实现可配置日志快照记录