白话Spring(基础篇)---AOP(实例篇-1)
2016-03-04 21:33
435 查看
[一知半解,就是给自己挖坑]
上文中,介绍了AOP的基本概念,接下来,我们看看AOP相关概念对应的实例及用法。本节我们先介绍AOP的实现方式的第一种方式:Spring提供的类org.springframework.aop.framework.ProxyFactoryBean。
准备工作:
a.操作系统:win7 x64
b.开发工具:eclipse mars j2ee版本,maven3.3.2,Spring 4,junit4.12
c.引入前面工程中的jar包至外,还需要引入的有:aspectjweaver,aoplliance,spring-aop
-------------------------------------------------------------------------------------------------------------------------------------
使用 ProxyFactoryBean 来创建 AOP 代理的最重要的优点之一是 IoC 可以管理通知和切入点。 这是一个非常的强大的功能,能够实现其他 AOP 框架很难实现的特定的方法。例如,一个通知本身可以引用应用对象(除了目标对象,它在任何AOP 框架中都可以引用应用对象),这完全得益于依赖注入所提供的可插入性。
--------------------------------------------------------------------------------------------------------------------------------------------------------
1.创建Spring091工程,工程结构图如下:
2.创建BaseAfterReturnAdvice.java文件,具体内容如下:
9.创建Main。java,具体内容如下:
10.创建beans.xml文件,具体内容如下:
现在,我们来解释一下这份配置文件:
a.配置文件中的id为baseBefore及其他3个bean就是我们所需要的4中通知,及advice。这些通知需要实现对应的接口。
接口的描述如下:
b.配置文件中的id为baseBusiness的bean是Spring要代理的对象,及当执行此对象中的方法时,触发4个advice
c.配置文件中的id为businessProxy的bean是Spring的ProxyFactoryBean。
d.属性proxyInterfaces指明需要代理的接口。
e.属性target指明需要代理的目标对象。
f.属性interceptorNames指明需要使用到的advice的类型。
注意:
1. ProxyFactoryBean的proxyInterfaces属性只支持使用字符串的方式进行注入,不支持使用Bean的依赖方式进行注入。
2.如果ProxyFactoryBean 的proxyInterfaces 属性没有 被设置,但是目标类实现了一个(或者更多) 接口,那么ProxyFactoryBean 将自动检测到这个目标类已经实现了至少一个接口,
一个基于JDK的代理将被创建 。被实际代理的接口将是目标类所实现的全部 接口;实际上,这和在proxyInterfaces 属性中列出目标类实现的每个接口的情况是一样的。然而,这将显著地减少工作量以及输入错误的可能性。
11.测试方法:运行main方法,观察控制台输出即可。
-------------------------------------------------------------------------------------------------------------------------------------------------------
至此,白话Spring(基础篇)---AOP(实例篇-1)结束
参考资料:
Spring官网:http://spring.io/docs
其他博文:http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example
上文中,介绍了AOP的基本概念,接下来,我们看看AOP相关概念对应的实例及用法。本节我们先介绍AOP的实现方式的第一种方式:Spring提供的类org.springframework.aop.framework.ProxyFactoryBean。
准备工作:
a.操作系统:win7 x64
b.开发工具:eclipse mars j2ee版本,maven3.3.2,Spring 4,junit4.12
c.引入前面工程中的jar包至外,还需要引入的有:aspectjweaver,aoplliance,spring-aop
-------------------------------------------------------------------------------------------------------------------------------------
使用 ProxyFactoryBean 来创建 AOP 代理的最重要的优点之一是 IoC 可以管理通知和切入点。 这是一个非常的强大的功能,能够实现其他 AOP 框架很难实现的特定的方法。例如,一个通知本身可以引用应用对象(除了目标对象,它在任何AOP 框架中都可以引用应用对象),这完全得益于依赖注入所提供的可插入性。
--------------------------------------------------------------------------------------------------------------------------------------------------------
1.创建Spring091工程,工程结构图如下:
2.创建BaseAfterReturnAdvice.java文件,具体内容如下:
package com.java.ingo.advice; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; /** *@author 作者 E-mail:ingo *@version 创建时间:2016年3月4日下午2:02:08 *类说明 */ public class BaseAfterReturnAdvice implements AfterReturningAdvice { /** * returnValue :切入点执行完方法的返回值,但不能修改 <br> * method :切入点方法 <br> * args :切入点方法的参数数组 <br> * target :目标对象 */ public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("====进入after()=========="); System.out.print(args[0] + "在"); System.out.print(target + "对象上被"); System.out.println(method + "方法删除了"); System.out.println("====退出after()==========="); } }3.创建BaseAfterThrowsAdvice.java文件,具体内容如下:
package com.java.ingo.advice; import java.lang.reflect.Method; import org.springframework.aop.ThrowsAdvice; /** *@author 作者 E-mail:ingo *@version 创建时间:2016年3月4日下午2:04:52 *类说明 */ public class BaseAfterThrowsAdvice implements ThrowsAdvice { /** * 通知方法,需要按照这种格式书写 * * @param method * 可选:切入的方法 * @param args * 可选:切入的方法的参数 * @param target * 可选:目标对象 * @param throwable * 必填 : 异常子类,出现这个异常类的子类,则会进入这个通知。 */ public void afterThrowing(Method method, Object[] args, Object target, Throwable throwable) { System.out.println("删除出错"); } }4.创建BaseAroundAdvice.java文件,具体内容如下:
package com.java.ingo.advice; import java.lang.reflect.Method; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.cglib.proxy.MethodProxy; /** *@author 作者 E-mail:ingo *@version 创建时间:2016年3月4日下午2:03:08 *类说明 */ public class BaseAroundAdvice implements MethodInterceptor { /** * invocation :连接点 */ public Object invoke(MethodInvocation invocation) throws Throwable { System.out.println("===========进入around==========="); // 调用方法的参数 Object[] args = invocation.getArguments(); // 调用的方法 Method method = invocation.getMethod(); // 获取目标对象 Object target = invocation.getThis(); // 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行 Object returnValue = invocation.proceed(); System.out.println("输出:" + args[0] + ";" + method + ";" + target + ";" + returnValue + "\n"); System.out.println("===========结束进入around==========="); return returnValue; } }5.创建BaseBeforeAdvice.java文件,具体内容如下:
package com.java.ingo.advice; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; /** *@author 作者 E-mail:ingo *@version 创建时间:2016年3月4日上午11:41:39 *类说明 */ public class BaseBeforeAdvice implements MethodBeforeAdvice { /** * method : 切入的方法 <br> * args :切入方法的参数 <br> * target :目标对象 */ public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("=进入before()============"); System.out.print("准备在" + target + "对象上用"); System.out.print(method + "方法进行对 '"); System.out.println(args[0] + "'进行删除!"); System.out.println("=退出before()============"); } }6.创建Customer.java文件,具体内容如下:
package com.java.ingo.entity; public class Customer { private String name; private String sex; private int age; public Customer() { super(); System.out.println("------创建人员-------"); } public Customer(String name, String sex, int age) { super(); this.name = name; this.sex = sex; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }7.创建IBaseBusiness.java文件,具体内容如下:
package com.java.ingo.service; import com.java.ingo.entity.Customer; /** *@author 作者 E-mail:ingo *@version 创建时间:2016年3月4日上午11:40:25 *类说明 */ public interface IBaseBusiness { /** * 用作代理的切入点方法 * * @param obj * @return */ public void delete(Customer obj); }8。创建BaseBusiness.java文件,具体内容如下:
package com.java.ingo.service.impl; import com.java.ingo.entity.Customer; import com.java.ingo.service.IBaseBusiness; /** *@author 作者 E-mail:ingo *@version 创建时间:2016年3月4日上午11:40:55 *类说明 */ public class BaseBusiness implements IBaseBusiness { /** * 切入点 */ public void delete(Customer obj) { System.out.println("||=====================||"); System.out.println("删除用户:"+obj.getName()); System.out.println("||=====================||"); } }
9.创建Main。java,具体内容如下:
package Main; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.java.ingo.entity.Customer; import com.java.ingo.service.IBaseBusiness; import com.java.ingo.service.impl.BaseBusiness; /** *@author 作者 E-mail:ingo *@version 创建时间:2016年3月4日上午11:46:52 *类说明 */ public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml"); IBaseBusiness business = (IBaseBusiness ) context.getBean("businessProxy"); business.delete(new Customer("Tom","male",22)); } }
10.创建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:p="http://www.springframework.org/schema/p" 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/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd" default-autowire="byName"> <!-- ==============================利用spring自己的aop配置================================ --> <!-- 声明一个业务类 --> <bean id="baseBusiness" class="com.java.ingo.service.impl.BaseBusiness" /> <!-- 声明通知类 --> <bean id="baseBefore" class="com.java.ingo.advice.BaseBeforeAdvice" /> <bean id="baseAfterReturn" class="com.java.ingo.advice.BaseAfterReturnAdvice" /> <bean id="baseAfterThrows" class="com.java.ingo.advice.BaseAfterThrowsAdvice" /> <bean id="baseAround" class="com.java.ingo.advice.BaseAroundAdvice" /> <!-- 使用ProxyFactoryBean 产生代理对象 --> <bean id="businessProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 代理对象所实现的接口 ,如果有接口可以这样设置 --> <property name="proxyInterfaces"> <value>com.java.ingo.service.IBaseBusiness</value> </property> <!-- 设置目标对象 --> <property name="target"> <ref local="baseBusiness" /> </property> <!-- 代理对象所使用的advice,即4种通知--> <property name="interceptorNames"> <list> <value>baseAfterReturn</value> <value>baseAround</value> <value>baseAfterThrows</value> <value>baseBefore</value> </list> </property> </bean> </beans>
现在,我们来解释一下这份配置文件:
a.配置文件中的id为baseBefore及其他3个bean就是我们所需要的4中通知,及advice。这些通知需要实现对应的接口。
接口的描述如下:
通知类型 | 接口 | 描述 |
Before | org.springframework.aop.MethodBeforeAdvice | 在目标方法之前执行 |
around | org.aopalliance.intercept.MethodInterceptor | 拦截对目标对象方法执行 |
after | org.springframework.aop.AfterReturningAdvice | 在目标方法之后执行 |
throws | org.springframework.aop.ThrowsAdvice | 目标方法发生错误是执行 |
c.配置文件中的id为businessProxy的bean是Spring的ProxyFactoryBean。
d.属性proxyInterfaces指明需要代理的接口。
e.属性target指明需要代理的目标对象。
f.属性interceptorNames指明需要使用到的advice的类型。
注意:
1. ProxyFactoryBean的proxyInterfaces属性只支持使用字符串的方式进行注入,不支持使用Bean的依赖方式进行注入。
2.如果ProxyFactoryBean 的proxyInterfaces 属性没有 被设置,但是目标类实现了一个(或者更多) 接口,那么ProxyFactoryBean 将自动检测到这个目标类已经实现了至少一个接口,
一个基于JDK的代理将被创建 。被实际代理的接口将是目标类所实现的全部 接口;实际上,这和在proxyInterfaces 属性中列出目标类实现的每个接口的情况是一样的。然而,这将显著地减少工作量以及输入错误的可能性。
11.测试方法:运行main方法,观察控制台输出即可。
-------------------------------------------------------------------------------------------------------------------------------------------------------
至此,白话Spring(基础篇)---AOP(实例篇-1)结束
参考资料:
Spring官网:http://spring.io/docs
其他博文:http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example
相关文章推荐
- 源码分析:Java堆的创建
- SPRING IN ACTION 第4版笔记-第六章RENDERING WEB VIEWS-002- Spring的JSP标签之form标签(<sf:input><sf:errors><sf:form>)
- java学习
- java中的方法
- Struts2基础(struts.xml文件)
- java中的二维数组
- Java知识复习
- java小基础
- java构造器、方法的重载与继承总结
- jni实现回调java函数
- Struts基础(Package配置详解)
- java程序初始化顺序初探
- 02.java键盘输入Scanner以及方法调用--02
- 如何查看JDK以及JAVA框架的源码
- 01. java入门
- 02.Java基础-标识符、关键字、数据类型--01
- Java开源测试工具汇总
- 如何把Eclipse工程import Exprot到Android Studio
- Spring MVC流程
- Java 多线程(三)——线程的生命周期