第三章 AOP 基于Schema的AOP

简介: <p class="cjk" align="LEFT" style="margin-bottom:0cm; widows:0; orphans:0"><span style="font-family:'DejaVu Sans Condensed'"><span style="font-size:14px">        基于</span></span><span style="font-

        基于Schema定义的切面和前现两种方式定义的切面,内容上都差不多,只是表现形式不一样而已。


3.7.1一般增强的使用


a、目标类
public class Target {
	public void say(){
		System.out.println("say...");
	}
	
	public String getName(int id,String name){
		System.out.println("getName...");
		return "MR"+name+id;
	}
	
	public void around(){
		System.out.println("around...");
	}
	
	public void targetThrow(){
		System.out.println("targetThrow");
		throw new RuntimeException("我是一个运行期异常...");
	}
}


b、 POJO(增强所在的类 )
public class Pojo {
	public void before() {
		System.out.println("前置增强");
	}

	public void afterReturning(String retName, int id, String name) {
		System.out.println("后置增强,返回值为:"+retName+" 入参为:"+id+"-"+name);
	}
	
	public Object around(ProceedingJoinPoint point) throws Throwable{
		System.out.println("方法执行之前");
		Object object = point.proceed();
		System.out.println("方法执行之后");
		return object;
	}
	
	public void throwEx(Exception ex){
		System.out.println("抛出异常增强,异常信息:"+ex.getMessage());
	}
	
	public void finalEx(){
		System.out.println("Final增强");
	}
}


c、 aop 命名空间与 Schema 方式配置

<?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">
	<!-- 目标类 -->
	<bean id="target" class="cn.framelife.spring.schema.Target"></bean>
	
	<!-- 增强所在的类 -->
	<bean id="advisor" class="cn.framelife.spring.schema.Pojo"></bean>
	
	<!-- 配置基于schema的切面 -->
	<aop:config proxy-target-class="true">
		<!-- 确定增强所在类,并引入 -->
		<aop:aspect ref="advisor">
			<!—
                          前置增强 
                          method是配置增强所在类中的方法
                        -->
			<aop:before method="before" pointcut="target(cn.framelife.spring.schema.Target)"/>
		
			<!—
                          后置增强 
                          Returning 是返回值,必须和method中的参数名是一样的
                          在Schema配置中,多个切点函数的与操作是and,或操作是or
                        -->
			<aop:after-returning method="afterReturning" pointcut="execution(* cn.framelife.spring.schema..getName(..)) and args(id,name)" returning="retName" arg-names="retName,id,name"/>
		
			<!-- 环绕增强 -->
			<aop:around method="around" pointcut="execution(* cn.framelife.spring.schema..around(..))"/>
		
			<!—
                         抛出异常增强 
                         throwing是异常对象,必须和method中的参数是一样的
                        -->
			<aop:after-throwing method="throwEx" pointcut="execution(* cn.framelife.spring.schema..targetThrow(..))" throwing="ex"/>
			
			<!-- Final增强 -->
			<aop:after method="finalEx" pointcut="execution(* cn.framelife.spring.schema..targetThrow(..))"/>
	</aop:config>
</beans>

d、测试

ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		Target target = (Target) context.getBean("target");
		target.say();
		target.getName(10, "Zhang");
		target.around();
		target.targetThrow();

e、结果

前置增强
say...
前置增强
getName...
后置增强,返回值为:MRZhang10 入参为:10-Zhang
前置增强
方法执行之前
around...
方法执行之后
前置增强
targetThrow
抛出异常增强,异常信息:我是一个运行期异常...
Final增强
Exception in thread "main" java.lang.RuntimeException: 我是一个运行期异常...

3.7.2引介增强的使用


我们还是使用3.6.2@DeclareParents中的例子:Waiter为目标类,然后让目标类拥有ISeller接口的功能:

http://blog.csdn.net/p_3er/article/details/9269407



a、两个接口与两个类


目标类与其接口:

[java]  view plain copy print ?
  1. public interface IWaiter {  
  2.     public void service();  
  3. }  

[java]  view plain copy print ?
  1. @Component  
  2. public class Waiter implements IWaiter {  
  3.     @Override  
  4.     public void service() {  
  5.         System.out.println("service");  
  6.     }  
  7. }  

运行期织入到目标类的功能类与其接口:

[java]  view plain copy print ?
  1. public interface ISeller {  
  2.     public void sell();  
  3. }  

[java]  view plain copy print ?
  1. public class Seller implements ISeller {  
  2.     @Override  
  3.     public void sell() {  
  4.         System.out.println("sell");  
  5.     }  
  6. }  

b、配置

<?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">
	<!-- 目标类 -->
	<bean id="waiter" class="cn.framelife.spring.schema.Waiter"></bean>
	
	<!-- 增强所在的类 -->
	<bean id="advisor" class="cn.framelife.spring.schema.Pojo"></bean>
	
	<aop:config proxy-target-class="true">
		<!—
虽然引介增强不需要在增强所在的类中定义一个方法用于增强的实现,但<aop:aspect ref="advisor">中的ref属性依然要指定一个增强Bean
-->

		<aop:aspect ref="advisor">
			<!—
引介增强 
	types-matching 目标类
	implement-interface 要织入目标类的接口
	default-impl 织入接口的实现类
-->
			<aop:declare-parents 
				types-matching="cn.framelife.spring.schema.IWaiter+" 
				implement-interface="cn.framelife.spring.schema.ISeller"
				default-impl="cn.framelife.spring.schema.Seller"/>
		</aop:aspect>
	</aop:config>
</beans>


c、测试

ApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
		IWaiter waiter = (IWaiter) context.getBean("waiter");
		waiter.service();
		ISeller seller = (ISeller)waiter;
		seller.sell();

d、结果

service
sell

目录
打赏
0
0
0
0
10
分享
相关文章
|
11月前
|
Spring5源码(30)-基于Schema的AOP
Spring5源码(30)-基于Schema的AOP
55 0
spring学习笔记(13)基于Schema配置AOP详解
<div class="markdown_views"> <h1 id="基于schema配置入门实例">基于Schema配置入门实例</h1> <p>除了基于@AspectJ注解的形式来实现AOP外,我们还可以在IOC容器中配置。先来看看一个常见的应用场景,在我们的web项目中,我们需要为service层配置事务,传统的做法是在每个业务逻辑方法重复下面配置中:</p>
2512 0
|
7月前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
AOP(面向切面编程)能够帮助我们在不修改现有代码的前提下,为应用程序添加新的功能或行为。Micronaut框架中的AOP模块通过动态代理机制实现了这一目标。AOP将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,提高模块化程度。在Micronaut中,带有特定注解的类会在启动时生成代理对象,在运行时拦截方法调用并执行额外逻辑。例如,可以通过创建切面类并在目标类上添加注解来记录方法调用信息,从而在不侵入原有代码的情况下增强应用功能,提高代码的可维护性和可扩展性。
147 1
什么是AOP面向切面编程?怎么简单理解?
本文介绍了面向切面编程(AOP)的基本概念和原理,解释了如何通过分离横切关注点(如日志、事务管理等)来增强代码的模块化和可维护性。AOP的核心概念包括切面、连接点、切入点、通知和织入。文章还提供了一个使用Spring AOP的简单示例,展示了如何定义和应用切面。
762 1
什么是AOP面向切面编程?怎么简单理解?
论面向方面的编程技术及其应用(AOP)
【11月更文挑战第2天】随着软件系统的规模和复杂度不断增加,传统的面向过程编程和面向对象编程(OOP)在应对横切关注点(如日志记录、事务管理、安全性检查等)时显得力不从心。面向方面的编程(Aspect-Oriented Programming,简称AOP)作为一种新的编程范式,通过将横切关注点与业务逻辑分离,提高了代码的可维护性、可重用性和可读性。本文首先概述了AOP的基本概念和技术原理,然后结合一个实际项目,详细阐述了在项目实践中使用AOP技术开发的具体步骤,最后分析了使用AOP的原因、开发过程中存在的问题及所使用的技术带来的实际应用效果。
142 5
|
7月前
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
【9月更文挑战第9天】AOP(面向切面编程)通过分离横切关注点提高模块化程度,如日志记录、事务管理等。Micronaut AOP基于动态代理机制,在应用启动时为带有特定注解的类生成代理对象,实现在运行时拦截方法调用并执行额外逻辑。通过简单示例展示了如何在不修改 `CalculatorService` 类的情况下记录 `add` 方法的参数和结果,仅需添加 `@Loggable` 注解即可。这不仅提高了代码的可维护性和可扩展性,还降低了引入新错误的风险。
75 13
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
这篇文章是Spring5框架的AOP切面编程教程,通过XML配置方式,详细讲解了如何创建被增强类和增强类,如何在Spring配置文件中定义切入点和切面,以及如何将增强逻辑应用到具体方法上。文章通过具体的代码示例和测试结果,展示了使用XML配置实现AOP的过程,并强调了虽然注解开发更为便捷,但掌握XML配置也是非常重要的。
Spring5入门到实战------11、使用XML方式实现AOP切面编程。具体代码+讲解
|
6月前
|
AOP面向切面编程
AOP面向切面编程
69 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等