AOP AspectJ注解
概念:
切面(aspect):用来切插业务方法的类。
连接点(joinpoint):是切面类和业务类的连接点,其实就是封装了业务方法的一些基本属性,作为通知的参数来解析。
通知(advice):在切面类中,声明对业务方法做额外处理的方法。
切入点(pointcut):业务类中指定的方法,作为切面切入的点。其实就是指定某个方法作为切面切的地方。
目标对象(target object):被代理对象。
AOP代理(aop proxy):代理对象。
AOP通知类型:
前置通知(before advice):在切入点之前执行。
后置通知(after returning advice):在切入点执行完成后,执行通知。
环绕通知(around advice):包围切入点,调用方法前后完成自定义行为。
异常通知(after throwing advice):在切入点抛出异常后,执行通知
依赖包:
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.10</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
Code:
package com.qhong; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component; public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Person person=(Person)context.getBean("babyPerson");
person.eatBreakfast();
System.out.println("===================================================");
person.eatLunch();
System.out.println("===================================================");
person.eatSupper();
System.out.println("===================================================");
person.drink("可乐");
System.out.println("===================================================");
}
} interface Person {
public void eatBreakfast();
public void eatLunch();
public void eatSupper();
public String drink(String name);
} @Component
class BabyPerson implements Person{ @Override
public void eatBreakfast() {
System.out.println("小Baby正在吃早餐");
} @Override
public void eatLunch() {
System.out.println("小Baby正在吃午餐");
} @Override
public void eatSupper() {
System.out.println("小Baby正在吃晚餐");
} @Override
public String drink(String name) {
return "小Baby在喝:"+name;
}
} @Component
@Aspect
class AdivceMethod { @Before("execution(* com.qhong.BabyPerson.*(..))")
// 匹配BabyPerson类所有的方法,注意*和com之间有个空格
public void beforeEat() {
System.out
.println("-------------------这里是前置增强,吃饭之前先洗小手!--------------------");
} @After("execution(* eatLunch(..))")
// 匹配该工程下所有的eatLunch方法
public void afterEat() {
System.out
.println("-------------------这里是后置增强,午饭吃完要睡午觉!--------------------");
} @Around("execution(* com.qhong.BabyPerson.eatSupper())")
// 匹配该工程下BabyPerson的eatLunch方法
public Object aroundEat(ProceedingJoinPoint pjp) throws Throwable {
System.out
.println("-------------------这里是环绕增强,吃晚饭前先玩一玩!-------------------");
Object retVal = pjp.proceed();
System.out
.println("-------------------这里是环绕增强,晚饭吃完后要得睡觉了!-------------------");
return retVal;
}
@AfterReturning(returning="rvt",pointcut="execution(* com.qhong.BabyPerson.drink(..))")
public void log(Object rvt) {
System.out
.println("-------------------这里是AfterReturning增强-------------------");
System.out.println("获取小Baby正在喝的饮料"+rvt);
System.out.println("记录每天喝的饮料容量"); }
}
beans.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-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 指定自动搜索bean组件、自动搜索切面类 -->
<context:component-scan base-package="com.qhong"/>
<!-- 启动@AspectJ支持 -->
<!-- proxy-target-class默认"false",更改为"ture"使用CGLib动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
Result:
-------------------这里是前置增强,吃饭之前先洗小手!--------------------
小Baby正在吃早餐
===================================================
-------------------这里是前置增强,吃饭之前先洗小手!--------------------
小Baby正在吃午餐
-------------------这里是后置增强,午饭吃完要睡午觉!--------------------
===================================================
-------------------这里是环绕增强,吃晚饭前先玩一玩!-------------------
-------------------这里是前置增强,吃饭之前先洗小手!--------------------
小Baby正在吃晚餐
-------------------这里是环绕增强,晚饭吃完后要得睡觉了!-------------------
===================================================
-------------------这里是前置增强,吃饭之前先洗小手!--------------------
-------------------这里是AfterReturning增强-------------------
获取小Baby正在喝的饮料小Baby在喝:可乐
记录每天喝的饮料容量
===================================================
Spring + AspectJ(基于注解:通过 AspectJ execution 表达式拦截方法)
package com.qhong; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component; public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
com.qhong.Greeting greeting = (com.qhong.Greeting) context.getBean("greetingImpl");
greeting.sayHello("Jack");
}
} interface Greeting {
void sayHello(String name);
} @Component
class GreetingImpl implements Greeting {
@Override
public void sayHello(String name) {
System.out.println("Hello! " + name);
}
} @Aspect
@Component
class GreetingAspect {
@Around("execution(* com.qhong.GreetingImpl.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
before();
Object result = pjp.proceed();
after();
return result;
} private void before() {
System.out.println("Before");
} private void after() {
System.out.println("After");
}
}
spring.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.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="com.qhong"/> <aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
Result:
Before
Hello! Jack
After
遇到的bug
java.lang.NoClassDefFoundError: org/springframework/beans/factory/NoUniqueBeanDefinitionException
遇到这个问题应该是groupid是org.springframework的各个依赖之间版本相差太大造成的问题,全都改成统一的就ok了。
http://tonylit.me/2016/06/29/spring%20aop-AspectJ%E6%B3%A8%E8%A7%A3%E6%96%B9%E5%BC%8F/
http://www.yiibai.com/spring/spring-aop-aspectj-annotation-example.html
http://blog.csdn.net/xiaoxian8023/article/details/17285809
http://www.kancloud.cn/evankaka/springlearning/119670
http://git.oschina.net/lujianing/aop_demo
https://my.oschina.net/huangyong/blog/159788
https://my.oschina.net/huangyong/blog/161338
https://my.oschina.net/huangyong/blog/161402
https://my.oschina.net/huangyong/blog/160769
https://my.oschina.net/huangyong/blog/170494
AOP AspectJ注解的更多相关文章
- Spring学习(十八)----- Spring AOP+AspectJ注解实例
我们将向你展示如何将AspectJ注解集成到Spring AOP框架.在这个Spring AOP+ AspectJ 示例中,让您轻松实现拦截方法. 常见AspectJ的注解: @Before – 方法 ...
- Spring——AOP(面向切面编程)@AspectJ注解方式
一.什么是AOP? AOP: (Aspect Oriented Programming)即面向切面编程. 试想这样的场景:项目中需要在业务方法执行完打印日志记录.最笨的办法就是在每个方法核心业务执行完 ...
- SSH深度历险(十) AOP原理及相关概念学习+AspectJ注解方式配置spring AOP
AOP(Aspect Oriented Programming),是面向切面编程的技术.AOP基于IoC基础,是对OOP的有益补充. AOP之所以能得到广泛应用,主要是因为它将应用系统拆分分了2个部分 ...
- Spring学习之旅(八)Spring 基于AspectJ注解配置的AOP编程工作原理初探
由小编的上篇博文可以一窥基于AspectJ注解配置的AOP编程实现. 本文一下未贴出的相关代码示例请关注小编的上篇博文<Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AO ...
- Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AOP编程比较
本篇博文用一个稍复杂点的案例来对比一下基于XML配置与基于AspectJ注解配置的AOP编程的不同. 相关引入包等Spring AOP编程准备,请参考小编的其他博文,这里不再赘述. 案例要求: 写一 ...
- spring AOP 之二:@AspectJ注解的3种配置
@AspectJ相关文章 <spring AOP 之二:@AspectJ注解的3种配置> <spring AOP 之三:使用@AspectJ定义切入点> <spring ...
- spring-AOP框架(基于AspectJ注解配置AOP)
基于AspectJ注解配置AOP 1.加入jar包: 要在Spring应用中使用AspectJ注解,必须在classpath下包含AspectJ类库:aopalliance.jar.aspectj.w ...
- Spring使用AspectJ注解和XML配置实现AOP
本文演示的是Spring中使用AspectJ注解和XML配置两种方式实现AOP 下面是使用AspectJ注解实现AOP的Java Project首先是位于classpath下的applicationC ...
- spring AOP编程--AspectJ注解方式
1. AOP 简介 AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, ...
随机推荐
- MQTT的学习研究(十一) IBM MQTT 简单发布订阅实例
package com.etrip.push; import com.ibm.mqtt.MqttAdvancedCallback; import com.ibm.mqtt.MqttClient; im ...
- $.data(elem, key, val) 和 elem.data(key, val)
var div1 = $("div"), div2 = $("div"); 1. div1.data("key", &quo ...
- 域渗透学习预备知识-IPC$的入侵防御
一.什么是IPC$ 以下段落引文自:http://www.xfocus.net/articles/200303/493.html IPC$(Internet Process Connection)是共 ...
- Egret P2 ( 一) 掉落的小球
实际效果(蛋疼这个gif制作软件,帧率太低....): 一 Egret和P2的坐标系 首先了解下P2和Egret的坐标系. 某人链接:http://blog.csdn.net/qilei2010/ar ...
- Windows Phone 上拉刷新、下拉刷新
ScrollViewer scrollViewer = new ScrollViewer(); // 构造函数 public MainPage() { InitializeComponent(); ; ...
- 解决:Bitmap too large to be uploaded into a texture exception
前几天拿锤子手机做测试,启动页面的闪屏直接黑屏.. 所以看下日志,百度一下 找到解决方案,特此记录. 简单说就是硬件加速的时候,对图片的大小有限制.不同设备可能有不同的最大值.这个问题悲催的地方是,程 ...
- ThinkPHP流程控制!
IF判断: 在thinkphp 中不能使用 <> 这样的尖括号: <if condition='表达式'> <elseif condition='表达式'/> &l ...
- 03.JMS深入
1.JMS API JMS API可以分为3个主要部分:公共API.点对点API和发布/订阅API.在JMS1.1中,公共API可被用于向一个队列或主题发送消息,或从其中接收消息.点对点API ...
- Linux救援模式
Linux系统使用版本:CentOS 6.5 救援模式有什么作用: ◆可以更改root密码: ◆恢复硬盘.文件系统操作: ◆系统启动不来的时候,只能通过救援模式来启动: 救援模式启动的步骤如下: 1. ...
- 使用jquery的$.post()时浏览器崩溃
代码: function verifyStepOne() { var phoneNumber = $("#phoneNumber"); var username = $(" ...