AOP联盟
面向切面编程(AOP)是一种编程技术,AOP联盟定义了一套用于规范AOP实现的底层API,现在已经推出了几个项目。
- ASM 轻量级字节码转换器
- AspectJ 一个面向切面的框架,拓展了JAVA语言
- CGLIB 用于类工件操作和方法拦截器的高级API
- JBoss-AOP 拦截和基于元数据的AO框架
AOP概述
面向切面编程是对面向对象编程的一种补充,面向切面编程提供了一种横向的切面逻辑,将与多个对象有关的公共模块分装成一个可重用模块。
- 横切关注点:一些具有横切多个不同软件模块的行为,横切关注点可以对某些方法进行拦截,拦截后对方法进行增强。
- 切面(Aspect):切面就是对横切关注点的抽象,这个切面可能切多个对象。
- 连接点(JoinPoint):连接点就是在程序执行过程中某个特定的点
- 切入点(PointCut):切入点是匹配连接点的拦截规则,在满足这个切入点连接点上运行通知。
- 通知(Advice):见切入点
- 目标对象(TargetObject):需要被切的对象
- 织入(Weaving):织入是把切面作用到目标对象,产生一个代理对象的过程
- 引入(Introduction):引入是在程序运行时给一个类声明额外的方法或者属性,即不需要为类实现一个接口,就能使用接口中的方法或者属性。
AOP实现
基于CGLIB动态代理的实现
- XML配置方式实现
以下是代码:
接口类
package com.SpringAOP;
/**
* Author:haozhixin
* Func: AOPXML实现
* Date: 20190808
*/
public interface Fruit {
void eat();
}
Apple类
package com.SpringAOP;
/**
* Author:haozhixin
* Func: AOPXML实现
* Date: 20190808
*/
public class Apple implements Fruit {
@Override
public void eat() {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("吃苹果");
}
}
Banana类
package com.SpringAOP;
/**
* Author:haozhixin
* Func: AOPXML实现
* Date: 20190808
*/
public class Banana implements Fruit{
@Override
public void eat() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("吃香蕉");
}
}
FruitHandler
package com.SpringAOP;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Author:haozhixin
* Func: 横切关注点,关注分别用了多长时间吃水果
* Date: 20190808
*/
public class FruitHandler {
public void StartEatFruit(){
System.out.print("开始吃水果的时间是:"+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));
}
public void EndEatFruit(){
System.out.print("开始吃水果的时间是:"+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));
}
}
SpringAopTest.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.SpringAOP"></context:component-scan>
<bean id="Apple" class="com.SpringAOP.Apple" scope="singleton" >
</bean>
<bean id="Banana" class="com.SpringAOP.Banana" scope="singleton" >
</bean>
<bean id="FruitHandler" class="com.SpringAOP.FruitHandler" scope="singleton" >
</bean>
<aop:config proxy-target-class="true"><!--一定要声明,不然main函数会报错,网上大部分解释都是错误的-->
<aop:aspect id="dateLog" ref="FruitHandler"><!--切面-->
<aop:pointcut id="eatFruit" expression="execution(* com.SpringAOP.Fruit.*(..))"/> <!--切点--> <!--注意第一个* 后边有空格-->
<aop:before method="StartEatFruit" pointcut-ref="eatFruit"></aop:before>
<aop:after method="EndEatFruit" pointcut-ref="eatFruit"></aop:after>
</aop:aspect>
</aop:config>
</beans>
SpringAopTest类
import com.SpringAOP.Apple;
import com.SpringAOP.Banana;
import com.SpringAOP.Fruit;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Author:haozhixin
* Func:
* Date:
*/
public class SpringAopTest {
public static void main(String []args){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:SpringAopTest.xml");
Fruit apple = (Apple)applicationContext.getBean("Apple");
Fruit banana = (Banana)applicationContext.getBean("Banana");
apple.eat();
System.out.println("-----休息一会------");
banana.eat();
}
}
- 注解方式实现
以下是代码
FruitAnnotationHandler类
package com.SpringAOP;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Author:haozhixin
* Func: SpringAOP 注解实现
* Date: 20190808
*/
@Component
@Aspect
public class FruitAnnotationHandler {
@Pointcut("execution(* com.SpringAOP.Fruit.*(..))")
public void eatFruit(){}
/***
* 前置通知
*/
@Before("eatFruit()")
public void StartEatFruit(){
System.out.print("开始吃水果的时间是:"+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));
}
/***
* 后置通知
*/
@After("eatFruit()")
public void EndEatFruit(){
System.out.print("开始吃水果的时间是:"+new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date()));
}
}
SpringAnnotationAopTest.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.SpringAOP"></context:component-scan>
<bean id="Apple" class="com.SpringAOP.Apple" scope="singleton" >
</bean>
<bean id="Banana" class="com.SpringAOP.Banana" scope="singleton" >
</bean>
<bean id="FruitAnnotationHandler" class="com.SpringAOP.FruitAnnotationHandler" scope="singleton" >
</bean>
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy><!--必须声明,不然切面不会生效-->
</beans>
SpringAnnotationAopTest
package com.Bean生命周期;
import com.SpringAOP.Apple;
import com.SpringAOP.Banana;
import com.SpringAOP.Fruit;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Author:haozhixin
* Func:
* Date:
*/
public class SpringAnnotationAopTest {
public static void main(String []args){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:SpringAnnotationAopTest.xml");
Fruit apple = (Apple)applicationContext.getBean("Apple");
Fruit banana = (Banana)applicationContext.getBean("Banana");
apple.eat();
System.out.println("-----休息一会------");
banana.eat();
}
}
以上就是基于CGLIB动态代理的相关AOP实现,如果对JDK感兴趣的同学可以自行百度搭建,这里不再赘述了~谢谢大家!
作者:select you from me
来源:优快云
转载请联系作者获得授权并注明出处。