Spring AOP(面向切面示例)
什么是AOP?
基本概念
切面(aspect):横切关注点被模块化的特殊对象。
通知(advice):切面必须要完成的工作。切面中的每个方向称之为通知。通知是在切面对象中的。
目标(target):被通知的对象。
代理(proxy):向目标对象应用通知后创建的对象。
连接点(joinpoint):目标对象的程序执行的某个特定位置。如某个方法调用前,调用后的位置。包括两个信息:1.目标程序的哪个方法?2.方法执行
前还是执行后?
切点(pointcut):每个类会有多个连接点,AOP通过切点定位到特定的边接点。
类比,连接点相当于数所成方圆 中的记录,而切点相当于查询条件。一个切点匹配多个连接点。
方法一(Annotation注解方式):
1.新建接口(IHuman),两个类(American和Chinese)继承该接口
package maya.entities; import org.springframework.stereotype.Component; public interface IHuman { public void eat(); public void sleep(); }
@Component public class American implements IHuman { @Override public void eat() { System.out.println("美国人在吃饭"); } @Override public void sleep() { System.out.println("美国人在睡觉"); } }
@Component public class Chinese implements IHuman { @Override public void eat() { System.out.println("中国人正在吃饭"); } @Override public void sleep() { System.out.println("中国人正在睡觉"); } }
2.建立切面类
package maya.aop; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class HumanAOP { @Before("execution(* maya.entities.*.eat(..))") public void beforeEat() { System.out.println("饭前洗手"); } @Before("execution(* maya.entities.*.sleep(..))") public void beforeSleep() { System.out.println("洗澡后睡觉"); } }
3.配置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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <context:component-scan base-package="maya.entities,maya.aop" ></context:component-scan> <!-- 启动第三方的aspectjweaver.jar中的功能 --> <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> </beans>
4.建立测试类,运行
package maya.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import maya.entities.American; import maya.entities.Chinese; public class Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Chinese c = (Chinese)context.getBean("chinese"); c.eat(); c.sleep(); American a = context.getBean(American.class); a.eat(); a.sleep(); } }
运行结果:
饭前洗手
中国人正在吃饭
洗澡后睡觉
中国人正在睡觉
饭前洗手
美国人在吃饭
洗澡后睡觉
美国人在睡觉
方法二xml(推荐):
1.新建接口(IHuman),两个类(American和Chinese)继承该接口
package maya.entities; public interface IHuman { public void eat(); public void sleep(); }
public class American implements IHuman { @Override public void eat() { System.out.println("美国人要吃饭了"); } @Override public void sleep() { System.out.println("美国人要睡觉了"); } }
public class Chinese implements IHuman { @Override public void eat() { System.out.println("中国人要吃饭了"); } @Override public void sleep() { System.out.println("中国人要睡觉了"); } }
2.建立切面类
package maya.aop; public class HumanAOP { public void beforeEat() { System.out.println("饭前洗手"); } public void afterEat() { System.out.println("饭后漱口"); } }
3.配置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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd" default-autowire="byName" > <bean id="chinese" class="maya.entities.Chinese"></bean> <bean id="american" class="maya.entities.American"></bean> <bean id="humanAOP" class="maya.aop.HumanAOP"></bean> <aop:config> <aop:pointcut expression="execution(* maya.entities.*.eat(..))" id="beforeEat"></aop:pointcut> <aop:pointcut expression="execution(* maya.entities.*.eat(..))" id="afterEat"></aop:pointcut> <aop:aspect id="ha" ref="humanAOP"> <aop:before method="beforeEat()" pointcut-ref="beforeEat"></aop:before> <aop:after method="afterEat()" pointcut-ref="afterEat"></aop:after> </aop:aspect> </aop:config> </beans>
4.建立测试类,运行
package maya.test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import maya.entities.IHuman; public class Test { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); IHuman c = (IHuman)context.getBean("american"); c.eat(); } }
运行结果:
饭前洗手
美国人要吃饭了
饭后漱口