1、依赖配置方式
测试方法:
public void test1() {
String filePath = System.getProperty("user.dir") + File.separator + "src/com/dmeo/aop"
+ File.separator + "spring.xml";
BeanFactory factory = new XmlBeanFactory(new FileSystemResource(filePath));
Shopping shopping = null;
System.out.println("不使用任何通知");
shopping = (Shopping) factory.getBean("shoppingImpl");
shopping.buySomething("something");
// shopping.buyAnything("anything");
System.out.println("使用前置通知");
shopping = (Shopping) factory.getBean("welcomeAdviceShop");
shopping.buySomething("type2");
shopping.buyAnything("anything");
}
spring.xml
<bean id="welcomeAdvice" class="com.dmeo.aop.WelcomeAdvice" />
<bean id="welcomeAdviceShop"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref local="shoppingImpl" />
</property>
<!-- 以下属性没有的话不会出错,interceptorNames如果没有配置,target的方法就不会被拦截 -->
<property name="proxyInterfaces">
<value>com.dmeo.aop.Shopping</value>
</property>
<property name="interceptorNames">
<list>
<value>welcomeAdvice</value>
</list>
</property>
</bean>
2.不干涉原先的bean配置,AOP真正的强悍啊,可以用来测试,添加日志等
1).单个通知
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd">
<bean id="customer" class="com.dmeo.aop.Customer">
<constructor-arg index="0">
<value>xh</value>
</constructor-arg>
<constructor-arg index="1">
<value>26</value>
</constructor-arg>
</bean>
<bean id="shoppingImpl" class="com.dmeo.aop.ShoppingImpl">
<property name="customer">
<ref local="customer" />
</property>
</bean>
<bean id="welcomeAdvice" class="com.dmeo.aop.WelcomeAdvice" />
<aop:config>
<aop:pointcut id="serviceOperation-before"
expression="execution(* com.dmeo.aop.*.*(..))" />
<aop:advisor pointcut-ref="serviceOperation-before"
advice-ref="welcomeAdvice" />
</aop:config>
注意前面的bean的引用以及AOP的配置。
上面的配置只能够对切面(方法)的一种行为进行拦截,比如WelcomeAdvice实现MethodBeforeAdvice,就只能在切点调用之前进行通知(前置通知)。(后置通知 AfterReturningAdvice、环绕通知 MethodInterceptor、异常通知 ThrowsAdvice)
下面给出对切面的所有行为进行拦截通知。
2).多个通知一起拦截
<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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
default-autowire="autodetect">
<aop:config>
<aop:aspect id="TestAspect" ref="aspectBean">
<!--配置com.dmeo.aop2包下所有类或接口的所有方法-->
<aop:pointcut id="businessService"
expression="execution(* com.dmeo.aop2.*.*(..))" />
<aop:before pointcut-ref="businessService" method="doBefore" />
<aop:after pointcut-ref="businessService" method="doAfter" />
<aop:around pointcut-ref="businessService" method="doAround" />
<aop:after-throwing pointcut-ref="businessService" method="doThrowing" throwing="ex" />
</aop:aspect>
</aop:config>
<bean id="aspectBean" class="com.dmeo.aop2.TestAspect" />
<bean id="aService" class="com.dmeo.aop2.AServiceImpl"></bean>
<bean id="bService" class="com.dmeo.aop2.BServiceImpl"></bean>
</beans>
测试类:
public static void main(String[] args) {
String filePath = "com/dmeo/aop2/spring.xml";
// 必须得用ApplicationContext
ApplicationContext factory = new ClassPathXmlApplicationContext(filePath);
aService = (AService) factory.getBean("aService");
bService = (BServiceImpl) factory.getBean("bService");
testThrow();
}
public static void testCall() {
System.out.println("Spring AOP test");
aService.fooA("test fooA");
aService.barA();
bService.fooB();
bService.barB("test barB", 0);
}
public static void testThrow() {
try {
bService.barB("call barB", 1);
} catch (IllegalArgumentException e) {
}
}
详细代码见附件~~~
重点说明:
《Spring参考手册》中定义了以下几个AOP的重要概念,结合以上代码分析如下:
-
切面(Aspect) :官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”,在本例中,“切面”就是类TestAspect所关注的具体行为,例如,AServiceImpl.barA()的调用就是切面TestAspect所关注的行为之一。“切面”在ApplicationContext中<aop:aspect>来配置。
-
连接点(Joinpoint) :程序执行过程中的某一行为,例如,AServiceImpl.barA()的调用或者BServiceImpl.barB(String _msg, int _type)抛出异常等行为。
-
通知(Advice) :“切面”对于某个“连接点”所产生的动作,例如,TestAspect中对com.spring.service包下所有类的方法进行日志记录的动作就是一个Advice。其中,一个“切面”可以包含多个“Advice”,例如TestAspect
-
切入点(Pointcut) :匹配连接点的断言,在AOP中通知和一个切入点表达式关联。例如,TestAspect中的所有通知所关注的连接点,都由切入点表达式execution(* com.spring.service.*.*(..))来决定
-
目标对象(Target Object) :被一个或者多个切面所通知的对象。例如,AServcieImpl和BServiceImpl,当然在实际运行时,Spring AOP采用代理实现,实际AOP操作的是TargetObject的代理对象。
-
AOP代理(AOP Proxy) 在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。默认情况下,TargetObject实现了接口时,则采用JDK动态代理,例如,AServiceImpl;反之,采用CGLIB代理,例如,BServiceImpl。强制使用CGLIB代理需要将
<aop:config>
的 proxy-target-class
属性设为true
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
modifiers-pattern:方法的操作权限
ret-type-pattern:返回值
declaring-type-pattern:方法所在的包
name-pattern:方法名
parm-pattern:参数名
throws-pattern:异常
其中,除ret-type-pattern和name-pattern之外,其他都是可选的。上例中,execution(* com.spring.service.*.*(..))表示com.spring.service包下,返回值为任意类型;方法名任意;参数不作限制的所有方法。
分享到:
相关推荐
本学习笔记将深入探讨Spring AOP的核心概念、工作原理以及实际应用。 1. **核心概念** - **切面(Aspect)**:切面是关注点的模块化,包含业务逻辑之外的横切关注点,如日志、事务管理。 - **连接点(Join Point...
Spring Aop 学习笔记
**Spring AOP 学习笔记及实现Demo** Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架中的一个重要组成部分,它提供了一种在不修改源代码的情况下,对程序进行功能增强的技术。AOP的主要目的...
NULL 博文链接:https://linres.iteye.com/blog/281221
,文章属于基础级文章,适合入门级的小伙伴,它的概念,应用场景,实现原理及Spring的AOP的开发。全称:面向切面编程(AspectOrientedProgramming),通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。...
Spring框架是Java开发中不可或缺的一部分,它为开发者提供了强大的依赖注入(IOC)和面向切面编程(AOP)功能,以及用于构建Web应用程序的MVC框架。Spring Boot则是基于Spring框架构建的应用程序启动器,旨在简化...
本笔记主要探讨了如何在Spring应用中使用AOP来实现横切关注点,如日志、事务管理、性能监控等。 首先,理解AOP的基本概念至关重要。AOP的核心是切面(Aspect),它封装了跨越多个对象的行为或责任。切面由两个主要...
SSH笔记主要围绕的是Spring框架中的AOP(面向切面编程)特性进行讲解,结合了动态代理和基于注解的配置方式。AOP是Spring框架的一个重要组成部分,它提供了一种模块化和解耦代码的方式,使得我们可以将关注点分离到...
本学习笔记主要涵盖了Java的基础知识,包括面向对象、集合、IO流、多线程、反射与动态代理以及Java 8的新特性等方面,旨在帮助初学者或有经验的开发者巩固和提升Java编程技能。 1. 面向对象(OOP):Java的核心是...
在本篇Spring学习笔记中,我们将深入探讨如何利用Spring配置文件来实现面向切面编程(AOP)。面向切面编程是Spring框架的核心特性之一,它允许我们把关注点分离,将横切关注点(如日志、事务管理、权限控制等)与...
【JBoss ESB 学习笔记】 JBoss ESB(Enterprise Service Bus,企业服务总线)是Red Hat公司开发的一款开源服务导向架构(SOA)平台,它为分布式应用程序提供了集成和互操作性。本笔记将深入探讨JBoss ESB的核心概念...
这份"Spring框架学习笔记"涵盖了Spring框架的基础知识、核心组件以及高级特性,对于初学者来说是一份宝贵的资料。 一、Spring框架概述 Spring框架是为了解决企业应用开发的复杂性而设计的,它提供了一个全面的基础...
SSH学习笔记3主要聚焦于三个Java企业级开发框架——STRUTS、SPRING和HIBERNATE的集成与应用。这三个框架是Java后端开发中非常重要的组件,它们各自负责不同的层面,共同构建了一个强大的MVC(Model-View-Controller...
第5篇 Java企业开发学习笔记(1.5.1)采用配置方式使用AOP,介绍了如何使用配置方式来实现AOP,包括创建AOP配置文件、配置AOP等步骤。 第6篇 Java企业开发学习笔记(5下)采用注解方式使用AOP,讲述了如何使用注解...
本笔记主要关注Spring Boot中的两个核心概念:事务管理和面向切面编程(AOP)。我们将深入探讨这两个主题,理解它们的工作原理以及如何在实际项目中应用。 ### 事务管理 事务是数据库操作的基本单元,确保数据的...
在本篇Spring学习笔记中,我们将探讨如何使用CGLIB库来实现AOP功能。 CGLIB(Code Generation Library)是一个强大的高性能的代码生成库,它被广泛用于动态代理和运行时织入AOP切面。在Spring中,如果目标类没有...
《良葛格JAVA 学习笔记》是由知名IT专家林信良,网名“良葛格”,在台湾大学电机工程学系的深厚学术背景基础上,结合其作为SUN教育训练中心讲师的丰富教学经验编写的。他的著作还包括《Spring 技术手册》,并且他...
Java JDK 6学习笔记是为Java初学者量身定制的一份宝贵资料,它涵盖了Java编程的基础概念、语法以及核心特性。这份PPT简体版旨在帮助读者快速掌握Java开发的基本技能,逐步成为一名合格的Java程序员。 Java JDK...