`
p_3er
  • 浏览: 55774 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

第三章 AOP 通过Java API创建增强

 
阅读更多


3.3.1增强类型

前置增强:org.springframework.aop.MethodBeforeAdvice

后置增强:org.springframework.aop.AfterReturningAdvice

环绕增强:org.aopalliance.intercept.MethodInterceptor

异常抛出增强:org.springframework.aop.ThrowsAdvice

引介增强:org.springframework.aop.support.DelegatingIntroductionInterceptor


3.3.2前置增强

就是在连接点方法执行之前执行的内容。
如:我们在UserDaoImpl的save()方法执行之前执行一些内容。

a、UserDaoUserDaoImpl:

  1. publicinterfaceUserDao{
  2. publicvoidsave();
  3. }
  1. publicclassUserDaoImplimplementsUserDao{
  2. publicvoidsave(){
  3. System.out.println("保存用户...");
  4. }
  5. }

b、创建一个增强类实现MethodBeforeAdvice接口
public class UserDaoBeforeAdvice implements MethodBeforeAdvice {
	public void before(Method method, Object[] args, Object object)
			throws Throwable {
		System.out.println("我是前置增强");
	}
}


c、配置
<!-- 把增强类交由spring管理 -->
	<bean id="userDaoBeforeAdvice" class="cn.framelife.spring.advice.UserDaoBeforeAdvice"></bean>

	<!-- 把目标类交由spring管理 -->
	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<!-- 
		设置代理类 
		p:target-ref 目标对象
		p:proxyInterfaces 代理所要实现的接口,也就是目标对象的接口
		p:interceptorNames 织入的增强Bean,可以是多个,用","号分开
	-->
	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames="userDaoBeforeAdvice"
		p:target-ref="userDao"
	 />

d、main方法中测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//通过代理来获取userDao对象
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、结果
我是前置增强
保存用户...

3.3.3后置增强

就是在连接点方法执行之后执行的内容。

a、UserDaoUserDaoImpl:

  1. publicinterfaceUserDao{
  2. publicvoidsave();
  3. }
  1. publicclassUserDaoImplimplementsUserDao{
  2. publicvoidsave(){
  3. System.out.println("保存用户...");
  4. }
  5. }

b、创建一个增强类实现AfterReturningAdvice接口
public class UserDaoAfterAdvice implements AfterReturningAdvice {
	@Override
	public void afterReturning(Object object, Method method, Object[] args,
			Object arg3) throws Throwable {
		System.out.println("我是后置增强");
	}
}



c、配置
<bean id="userDaoBeforeAdvice" class="cn.framelife.spring.advice.UserDaoBeforeAdvice"></bean>
	<bean id="userDaoAfterAdvice" class="cn.framelife.spring.advice.UserDaoAfterAdvice"></bean>

	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	
	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames="userDaoBeforeAdvice,userDaoAfterAdvice"
		p:target-ref="userDao"
	 />


d、main方法中测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//通过代理来获取userDao对象
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、结果
保存用户...
我是后置增强


3.3.4环绕增强

环绕增强与struts2AOP类似。



a、UserDaoUserDaoImpl:

  1. publicinterfaceUserDao{
  2. publicvoidsave();
  3. }
  1. publicclassUserDaoImplimplementsUserDao{
  2. publicvoidsave(){
  3. System.out.println("保存用户...");
  4. }
  5. }

b、创建一个增强类实现MethodInterceptor接口
public class UserDaoSurroundAdvice implements MethodInterceptor {

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		System.out.println("环绕增强在方法前执行...");
		Object object = invocation.proceed();
		System.out.println("环绕增强在方法后执行...");
		return object;
	}

}


c、配置
<bean id="userDaoSurroundAdvice" class="cn.framelife.spring.advice.UserDaoSurroundAdvice"></bean>
	
	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames=" userDaoSurroundAdvice"
		p:target-ref="userDao"
	 />



d、main方法中测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//通过代理来获取userDao对象
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、结果
环绕增强在方法前执行...
保存用户...
环绕增强在方法后执行...


3.3.5异常抛出增强

就是在方法出现异常之后执行的代码。



a、UserDaoUserDaoImpl:

  1. publicinterfaceUserDao{
  2. publicvoidsave();
  3. }
publicclassUserDaoImplimplementsUserDao{
 publicvoidsave(){
 System.out.println("保存用户...");
 //使方法在运行的时候抛出一个异常
  throw new RuntimeException("运行时异常...");

}
}


b、创建一个增强类实现ThrowsAdvice接口
public class UserDaoThrowsAdvice implements ThrowsAdvice {
	public void afterThrowing(Method method,Object[] args,Object taglet,Exception ex)throws Throwable{
		System.out.println("我是异常抛出接口");
		System.out.println(method.getName());
		System.out.println(ex.getMessage());
	}
}



c、配置
<bean id="userDaoThrowAdvice" class="cn.framelife.spring.advice.UserDaoThrowsAdvice"></bean>

<!--
	 p:proxyTargetClass="false"
	如果目标对象是一个类,而不是一个接口,我们设置为true
-->
	<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<bean id="adviceUserDao" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:proxyInterfaces="cn.framelife.spring.dao.UserDao"
		p:interceptorNames="userDaoThrowAdvice"
		p:target-ref="userDao"
		p:proxyTargetClass="false"
	 />




d、main方法中测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		//通过代理来获取userDao对象
		UserDao userDao = (UserDao) context.getBean("adviceUserDao");
		userDao.save();

f、结果
保存用户...
Exception in thread "main" java.lang.RuntimeException: 运行时异常...
	at cn.framelife.spring.dao.impl.UserDaoImpl.save(UserDaoImpl.java:12)
	at cn.framelife.spring.dao.impl.UserDaoImpl$$FastClassByCGLIB$$18bd6dee.invoke(<generated>)
	at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191)
	at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:688)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
	at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:124)我是异常抛出接口
save
运行时异常...

	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
	at org.springframework.aop.framework.Cglib2AopProxy$DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:621)
	at cn.framelife.spring.dao.impl.UserDaoImpl$$EnhancerByCGLIB$$5bbe38b0.save(<generated>)
	at cn.framelife.spring.test.Test.main(Test.java:17)


3.3.6引介增强

引介增强是为目标类创建新的方法和属性,引介增强的连接点是类级别的,不是方法级别的。通过引介增强,我们可以为目标类添加一个接口的实现,即原来目标类未实现某个接口,通过引介增强可以为目标类创建实现某个接口的代理。




a、UserDaoUserDaoImpl:

  1. publicinterfaceUserDao{
  2. publicvoidsave();
  3. }
  1. publicclassUserDaoImplimplementsUserDao{
  2. publicvoidsave(){
  3. System.out.println("保存用户...");
  4. }
  5. }


b、新建一个接口AInterface
public interface AInterface {
	public void say();
}



c、增强类继承DelegatingIntroductionInterceptor实现AInterface
public class IntroductionAdvice extends DelegatingIntroductionInterceptor implements AInterface {
	/*
	 * 实现AInterface中的方法
	 */
	public void say() {
		System.out.println("UserDao要说话");
	}

	/*
	 * 重写DelegatingIntroductionInterceptor的invoke方法
	 */
	public Object invoke(MethodInvocation mi) throws Throwable {
		System.out.println("方法执行前执行");
		System.out.println(mi.getClass().getName());
		System.out.println(mi.getMethod().getName());
		Object object = super.invoke(mi);
		System.out.println("方法执行后执行");
		return object;
	}	
}




d、配置

<bean id="userDao" class="cn.framelife.spring.dao.impl.UserDaoImpl"></bean>

	<bean id="introductionAdvice" class="cn.framelife.spring.advice.IntroductionAdvice"></bean>
	<!-- 
		代理类设置
		p:proxyTargetClass="true" 引介增强一定要通过创建子类来生成代理,所以要设置为true。
			也不需要配置p:proxyInterfaces目标类的接口
		p:interfaces 引介增强所实现的接口
	 -->
	<bean id="aProxy" 
		class="org.springframework.aop.framework.ProxyFactoryBean"
		p:interfaces="cn.framelife.spring.dao.AInterface" 
		p:interceptorNames="introductionAdvice"
		p:target-ref="userDao" 
		p:proxyTargetClass="true" />

e、main方法中测试
ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		UserDao userDao = (UserDao) context.getBean("aProxy");
		userDao.save();
		
		System.out.println("-------------");
		
		AInterface a = (AInterface)userDao;
		a.say();
		
		System.out.println("-------------");
		userDao.save();


f、结果
方法执行前执行
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
save
保存用户...
方法执行后执行
-------------
方法执行前执行
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
say
UserDao要说话
方法执行后执行
-------------
方法执行前执行
org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation
save
保存用户...
方法执行后执行







分享到:
评论

相关推荐

    第三章:Spring AOP API 设计与实现1

    13. **JDK AopProxy实现 - JdkDynamicAopProxy**:当目标对象实现了至少一个接口时,Spring使用Java动态代理来创建AOP代理。 14. **CGLIB AopProxy实现 - CglibAopProxy**:对于没有接口的目标对象,Spring使用...

    第3章 Spring AOP.ppt

    1. **JDK 动态代理**:基于Java反射API,适用于目标对象实现了接口的情况。Spring默认会尝试使用JDK动态代理来创建AOP代理对象。 2. **CGLIB 代理**:当目标对象没有实现接口时,Spring会使用CGLIB库来生成目标对象...

    java文件上传,断点续传+aop操作日志

    在Java中,通常使用Servlet API或者第三方库如Apache Commons FileUpload来实现。Servlet 3.0及以上版本提供了内置的Part接口支持文件上传,而FileUpload库则提供更灵活的配置和错误处理机制。在处理文件上传时,...

    java编程各类api

    在Java中,API包括了Java核心库(JDK)和许多第三方库。 1. **Java核心API**: - **IO流**:Java.IO包包含了处理输入输出操作的各种类,如InputStream、OutputStream、Reader、Writer等,用于读写文件、网络数据...

    java api文档jdk-6u30-apidocs

    2. **动态代理增强**:增强了Java反射机制,允许创建动态代理类,方便实现回调和AOP(面向切面编程)。 3. **Scripting API**:允许在Java应用程序中集成脚本语言,如JavaScript、Groovy等。 4. **XML改进**:包括...

    aopalliance.jar包

    aopalliance.jar并不直接处理织入,但它的接口为第三方AOP框架提供了支持。 **使用场景** aopalliance-1.0.jar通常与Spring框架一起使用,Spring AOP是Spring框架的一部分,它实现了AOP联盟的接口,使得用户可以在...

    第三章 Spring MVC Servlet API与Json的支持

    3. 异步请求(如AJAX)中,通过`@ResponseBody`返回JSON数据,更新页面部分区域。 4. 实现RESTful API,使用HTTP动词(GET, POST, PUT, DELETE)和资源路径,配合JSON数据进行增删查改操作。 综上所述,Spring MVC...

    Java高级程序设计实战教程第三章-Java反射机制.pptx

    Java反射机制是Java编程语言中的一个强大工具,它允许程序在...通过本章的学习,读者将掌握Java反射机制的核心概念,了解如何在实际项目中运用反射,以及其优缺点。通过实践和练习,进一步巩固反射机制的理解和应用。

    AOP在Android中的使用(作为依赖库)

    在Java领域,Spring框架是AOP应用的典型代表,但在Android开发中,由于原生API并未直接支持AOP,我们需要借助第三方库来实现这一功能。 在Android中,AOP通常用于提升代码的可维护性和可扩展性。通过在不修改原有...

    JDK6 API.zip

    4. **动态代理**: 新增了`java.lang.reflect.Proxy`类,用于创建动态代理对象,可以方便地实现面向切面编程(AOP)。 5. **Swing增强**: JDK6对Swing组件进行了优化,添加了新的布局管理器,改进了外观和性能。 6. *...

    java常用API大全1

    3. Spring2.5_API.chm:Spring框架是Java企业级应用开发中的一个核心框架,2.5版本是其历史上的一个重要里程碑。这个API文档详细列出了Spring框架的核心组件,如依赖注入、AOP(面向切面编程)、数据访问/集成、Web...

    Java Web编程宝典-十年典藏版.pdf.part2(共2个)

    第3章前人栽树后人乘凉 ——、JSP内置对象 3.1 本章学习任务 3.1.1 本章知识体系 3.1.2 实例开发任务 3.2 简化开发JSP内置对象概述 3.2.1 为什么需要JSP内置对象 3.2.2 内置对象及其使用场合 3.3 out输出对象的应用 ...

    从零开始学java web

    第三章:JavaScript基础 JavaScript是Web开发中的重要脚本语言,用于实现页面的动态效果和用户交互。本章将讲解变量、数据类型、函数、DOM操作等基础知识。 第四章:Servlet与JSP概述 Servlet是Java Web的核心组件...

    《轻量级Java EE企业应用实战(第三版) 第4章第1节的源代码

    以上是对《轻量级Java EE企业应用实战(第三版) 第4章第1节源代码》可能涉及的一些核心知识点的详细解析,通过深入学习和实践这部分源代码,读者可以更好地理解和掌握Java EE开发的基本技术和最佳实践。

    JAVA WEB开发源码

    3. **第三章:JSP** - JSP(JavaServer Pages)用于动态网页生成,讲解JSP语法、EL(Expression Language)和JSTL(JavaServer Pages Standard Tag Library)。 4. **第四章:MVC模式** - 介绍Model-View-...

    java web开发典型模块大全(11~22章)完整

    3. **JDBC数据库操作**(13章):Java Database Connectivity允许Java程序与各种数据库进行交互。学习如何使用JDBC连接数据库,执行SQL语句,以及事务管理,是Java Web开发者必备技能。 4. **JSTL和EL表达式**(14...

    java必须第三方jar文件

    描述中提到的"在这里拥有你想要的第3方jar文件"表明可能有一个资源库或者下载站点,专门收集和提供各种Java开发所需的第三方JAR包。这对于开发者来说是非常宝贵的资源,因为他们可以快速找到并引入需要的库,而无需...

    Java开发典型模块大全源代码

    2. **第3章:面向对象编程** - Java是一种面向对象的语言,这一章讲解了类、对象、封装、继承和多态等核心概念。理解这些概念对于编写可维护、可扩展的代码至关重要。 3. **第4章:异常处理** - 异常处理是Java程序...

    基于 coolq-http-api 的 java sdk, 使用 JFinal 框架.zip

    首先,CoolQ HTTP API 是一个插件,允许第三方程序通过HTTP接口与QQ机器人进行交互。它可以处理各种任务,如接收和发送消息、管理群组成员等。使用 CoolQ HTTP API,开发者可以构建自己的应用,实现QQ机器人的自定义...

    《Java语言程序设计(进阶篇)》 课后习题第27章代码chapter27.rar

    《Java语言程序设计(进阶篇)》是深入学习Java编程的一本重要教材,而第27章的课后习题通常涵盖了高级特性和实践应用,对于提升编程技能至关重要。这个压缩包“chapter27.rar”包含了该章节的源代码示例,帮助读者...

Global site tag (gtag.js) - Google Analytics