Spring1.x, 2.x, 3.x 对于AOP的实现方式不一样。
Spring AOP是通过动态代理模式实现的,利用了java的反射机制。
在了解动态代理之前,先要知道什么是静态代理。
代理模式,就是在客户类和目标类之间增加了一个代理类,这个代理类和目标类实现了同样的借口。这样,客户类通过调用代理类来间接的访问目标类。在代理类中调用目标类同样接口的方法。这样在代理类中就可以在调用目标类的方法之前和之后做一些操作。
静态代理,是指在代理类的构造函数中静态地制定了目标类。所谓静态,就是指在编写代码的时候制定,这样编译之后就不能改了。
动态代理,是利用了java的反射机制,在运行时动态地制定目标类。具体实现方式是,代理类实现java.lang.reflect.InvocationHandler接口,实现接口中的invoke()方法,在Method.invoke(targetObject, args);调用之前和之后可以做一些操作。在代理类中自定义一个set方法,或者叫createProxy(Object targetObject),方法签名中有一个参数,是目标类。注意,这里目标类的类型是Object。所以,可以在运行时指定任何需要的目标类(目标类必须实现一个接口)。在这个方法中调用Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)来生成实现同一接口(目标类实现的接口)的代理类。Proxy.newProxyInstance()方法返回的是一个Object类型对象,在客户类中可以通过强制类型转换,把该对象转换成接口。然后调用该接口的业务方法,就会触发InvocationHandler接口实现类中的invoke()方法,从而达到代理的目的。
Spring1.x中的AOP是侵入式的,advice需要实现spring的接口MethodBeforeAdvice和AfterReturningAdvice,在applicationContext.xml中配置org.springframework.aop.framework.ProxyFactoryBean类作为代理类。例如
<bean id="userProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
在其中指定接口列表和拦截器列表(也就是advice列表),同时指定目标类。例如:
-----------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- spring1.x -->
<!-- 定义目标类 -->
<bean id="userTarget" class="com.freesky.proxy.UserTargetImpl" />
<!-- 定义通知 -->
<!-- 前置通知 -->
<bean id="beforeLogAdvice" class="com.freesky.aop.BeforeLogAdvice" />
<!-- 后置通知 -->
<bean id="afterLogAdvice" class="com.freesky.aop.AfterLogAdvice" />
<!-- 代理类作用: 生成代理类,织入通知 -->
<bean id="userProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces">
<!-- 可以添加多个接口 -->
<list>
<value>com.freesky.proxy.IUser</value>
</list>
</property>
<!-- 引入通知 -->
<property name="interceptorNames">
<list>
<value>beforeLogAdvice</value>
<value>afterLogAdvice</value>
</list>
</property>
<!-- 目标对象 -->
<property name="target" ref="userTarget" />
</bean>
</beans>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- spring1.x -->
<!-- 定义目标类 -->
<bean id="userTarget" class="com.freesky.proxy.UserTargetImpl" />
<!-- 定义通知 -->
<!-- 前置通知 -->
<bean id="beforeLogAdvice" class="com.freesky.aop.BeforeLogAdvice" />
<!-- 后置通知 -->
<bean id="afterLogAdvice" class="com.freesky.aop.AfterLogAdvice" />
<!-- 代理类作用: 生成代理类,织入通知 -->
<bean id="userProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces">
<!-- 可以添加多个接口 -->
<list>
<value>com.freesky.proxy.IUser</value>
</list>
</property>
<!-- 引入通知 -->
<property name="interceptorNames">
<list>
<value>beforeLogAdvice</value>
<value>afterLogAdvice</value>
</list>
</property>
<!-- 目标对象 -->
<property name="target" ref="userTarget" />
</bean>
</beans>
------------------------------------------------------------------------------------------
Spring2.x就不需要代码实现spring的接口,advice类就是一个pojo。在applicationContext.xml中通过<aop:config>来配置。其中引入了<aop:pointcut>。配置文件略显繁琐。完整的配置如下:
--------------------------------------------------------------------------------
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- spring2.x后 -->
<!-- 目标对象 -->
<bean id="userImpl" class="com.freesky.proxy.impl.UserTargetImpl" />
<!-- 通知 -->
<bean id="logAdvice" class="com.freesky.advice.LogAdvice" />
<aop:config>
<aop:aspect id="logAspect" ref="logAdvice">
<!-- 切入点 -->
<!--
<aop:pointcut id="beforePointCut" expression="execution(* sayHello*(..))" />
<aop:pointcut id="afterPointCut" expression="execution(* sayHello*(..))" />
-->
<aop:pointcut id="beforePointCut" expression="execution(* com.freesky.proxy.impl..*.*(..))" />
<aop:pointcut id="afterPointCut" expression="execution(* sayHello*(..))" />
<!-- 织入(通知作用于切入点) -->
<aop:before method="beforeLog" pointcut-ref="beforePointCut" />
<aop:after method="afterLog" pointcut-ref="afterPointCut" />
</aop:aspect>
</aop:config>
</beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- spring2.x后 -->
<!-- 目标对象 -->
<bean id="userImpl" class="com.freesky.proxy.impl.UserTargetImpl" />
<!-- 通知 -->
<bean id="logAdvice" class="com.freesky.advice.LogAdvice" />
<aop:config>
<aop:aspect id="logAspect" ref="logAdvice">
<!-- 切入点 -->
<!--
<aop:pointcut id="beforePointCut" expression="execution(* sayHello*(..))" />
<aop:pointcut id="afterPointCut" expression="execution(* sayHello*(..))" />
-->
<aop:pointcut id="beforePointCut" expression="execution(* com.freesky.proxy.impl..*.*(..))" />
<aop:pointcut id="afterPointCut" expression="execution(* sayHello*(..))" />
<!-- 织入(通知作用于切入点) -->
<aop:before method="beforeLog" pointcut-ref="beforePointCut" />
<aop:after method="afterLog" pointcut-ref="afterPointCut" />
</aop:aspect>
</aop:config>
</beans>
-----------------------------------------------------------------------------------------------------
Spring3.x在AOP方面大大简化了开发工作量,通过annotation注解的方式在java代码中配置,而applicationContex.xml中只要一个配置<aop:aspectj-autoproxy />就可以自动实现AOP了。当然这个配置要和另外两个配置以前使用。
<context:annotation-config />
<context:component-scan base-package="com.freesky"/>
完整的配置如下:
------------------------------------------------------------------
<?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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
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">
<context:annotation-config />
<context:component-scan base-package="com.itsoft"/>
<aop:aspectj-autoproxy />
</beans>
<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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
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">
<context:annotation-config />
<context:component-scan base-package="com.itsoft"/>
<aop:aspectj-autoproxy />
</beans>
------------------------------------------------------------------
参考文献:
Spring1.x 2.x 动态代理
Spring AOP动态代理原理与实现方式
Spring3.x
spring AOP @Around @Before @After 区别
相关推荐
Spring 2.x aop配置详解 Spring 2.x aop配置详解 Spring 2.x aop配置详解 Spring 2.x aop配置详解 Spring 2.x aop配置详解 Spring 2.x aop配置详解
NULL 博文链接:https://baobeituping.iteye.com/blog/1199769
全书分3篇共21章,具体内容包括:Spring环境的安装与使用、JSP与JSTL简介、 Spring基础概念与工具、用SpringJdbcTemplate访问数据库、使用Mayen工程、Spring MVC编程、基于 MVC的资源共享网站设计、Spring的AOP编程...
Spring 3.x 新特性全部介绍 http://static.springsource.org/spring/docs/3.1.0.RELEASE/spring-framework-reference/html/new-in-3.1.html 1、基于annotation的cache服务,这个非常好 这个最早源于spring2.x时代...
博文链接:https://log-cd.iteye.com/blog/213445
精通Spring4.x企业应用开发实战(PDF、包含源码)核心讲解了IOC、AOP、Spring事务,Spring MVC 等,简单介绍了Spring boot、hibernate、mybatis等
Spring2.5提供了更灵活的配置方法, 本文档详细介绍了Spring2.x通过XML文件和Annotation如何配置Spring bean,事务管理配置,AOP的详细配置,以及其他Spring所提供支持的配置。
spring 3.x教程 spring 3.x教程 spring 3.x教程
《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...
spring4.x-project ...文章地址:Spring4.x基础配置(三):Spring AOP Spring4.x常用配置(一):Bean的Scope Github项目地址:spring4.x-scope 码云项目地址:spring4.x-scope 文章地址:Spring4.x常用配置(一):
spring-aop-4.2.4.RELEASE.jar spring-aspects-4.2.4.RELEASE.jar spring-beans-4.2.4.RELEASE.jar spring-context-4.2.4.RELEASE.jar spring-context-support-4.2.4.RELEASE.jar spring-core-4.2.4.RELEASE.jar ...
======================================================================== <br>第1篇 概述 第1章 Spring概述 第2章 快速入门 第2篇 Spring核心技术 第3章 IoC容器概述 第4章 在IoC容器中...
======================================================================== <br>第1篇 概述 第1章 Spring概述 第2章 快速入门 第2篇 Spring核心技术 第3章 IoC容器概述 第4章 在IoC容器中...
第1章:对Spring框架进行宏观性的概述,力图使读者建立起对Spring整体性的认识。 第2章:通过一个简单的例子展现开发Spring Web应用的整体过程,通过这个实例,读者可以快速跨入Spring Web应用的世界。 第3章:...
《Spring3.x企业应用开发实战》是在《精通Spring2.x——企业应用开发详解》的基础上,经过历时一年的重大调整改版而成的,本书延续了上一版本追求深度,注重原理,不停留在技术表面的写作风格,力求使读者在熟练...
精通Spring 4.x 企业应用开发实战,快速入门,ioc,Sring AOP, 事务,spring 对DAO的支持,spring Cache,等相关技术
基于Spring 4.x企业应用开发实战。AOP概述、基础知识、创建切面、创建增强类、自动创建代理,
主要技术:springMVC springSecurity3.x Mybaits3.x mysql log4j md5 主要功能有: 用户管理 角色管理 资源管理 服务器配置管理 登陆信息管理 操作日志管理 查询用户 角色列表 资源列表 预警设置 用户登录记录 ...