第三章 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

目录
相关文章
|
Java Spring
Spring5源码(30)-基于Schema的AOP
Spring5源码(30)-基于Schema的AOP
94 0
|
XML Java 数据格式
Spring5参考指南:基于Schema的AOP
Spring5参考指南:基于Schema的AOP
|
Java Spring 数据格式
spring学习笔记(13)基于Schema配置AOP详解
<div class="markdown_views"> <h1 id="基于schema配置入门实例">基于Schema配置入门实例</h1> <p>除了基于@AspectJ注解的形式来实现AOP外,我们还可以在IOC容器中配置。先来看看一个常见的应用场景,在我们的web项目中,我们需要为service层配置事务,传统的做法是在每个业务逻辑方法重复下面配置中:</p>
2604 0
|
2月前
|
XML 安全 Java
使用 Spring 的 @Aspect 和 @Pointcut 注解简化面向方面的编程 (AOP)
面向方面编程(AOP)通过分离横切关注点,如日志、安全和事务,提升代码模块化与可维护性。Spring 提供了对 AOP 的强大支持,核心注解 `@Aspect` 和 `@Pointcut` 使得定义切面与切入点变得简洁直观。`@Aspect` 标记切面类,集中处理通用逻辑;`@Pointcut` 则通过表达式定义通知的应用位置,提高代码可读性与复用性。二者结合,使开发者能清晰划分业务逻辑与辅助功能,简化维护并提升系统灵活性。Spring AOP 借助代理机制实现运行时织入,与 Spring 容器无缝集成,支持依赖注入与声明式配置,是构建清晰、高内聚应用的理想选择。
394 0
|
1月前
|
监控 Java Spring
AOP 切面编程
AOP(面向切面编程)通过动态代理在不修改源码的前提下,对方法进行增强。核心概念包括连接点、通知、切入点、切面和目标对象。常用于日志记录、权限校验、性能监控等场景,结合Spring AOP与@Aspect、@Pointcut等注解,实现灵活的横切逻辑管理。
357 6
AOP 切面编程
|
1月前
|
XML Java 数据格式
《深入理解Spring》:AOP面向切面编程深度解析
Spring AOP通过代理模式实现面向切面编程,将日志、事务等横切关注点与业务逻辑分离。支持注解、XML和编程式配置,提供五种通知类型及丰富切点表达式,助力构建高内聚、低耦合的可维护系统。
|
3月前
|
人工智能 监控 安全
Spring AOP切面编程颠覆传统!3大核心注解+5种通知类型,让业务代码纯净如初
本文介绍了AOP(面向切面编程)的基本概念、优势及其在Spring Boot中的使用。AOP作为OOP的补充,通过将横切关注点(如日志、安全、事务等)与业务逻辑分离,实现代码解耦,提升模块化程度、可维护性和灵活性。文章详细讲解了Spring AOP的核心概念,包括切面、切点、通知等,并提供了在Spring Boot中实现AOP的具体步骤和代码示例。此外,还列举了AOP在日志记录、性能监控、事务管理和安全控制等场景中的实际应用。通过本文,开发者可以快速掌握AOP编程思想及其实践技巧。
|
3月前
|
监控 Java Spring
AOP切面编程快速入门
AOP(面向切面编程)通过分离共性逻辑,简化代码、减少冗余。它通过切点匹配目标方法,在不修改原方法的前提下实现功能增强,如日志记录、性能监控等。核心概念包括:连接点、通知、切入点、切面和目标对象。Spring AOP支持多种通知类型,如前置、后置、环绕、返回后、异常通知,灵活控制方法执行流程。通过@Pointcut可复用切点表达式,提升维护性。此外,结合自定义注解,可实现更清晰的切面控制。
317 5
Micronaut AOP与代理机制:实现应用功能增强,无需侵入式编程的秘诀
AOP(面向切面编程)能够帮助我们在不修改现有代码的前提下,为应用程序添加新的功能或行为。Micronaut框架中的AOP模块通过动态代理机制实现了这一目标。AOP将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,提高模块化程度。在Micronaut中,带有特定注解的类会在启动时生成代理对象,在运行时拦截方法调用并执行额外逻辑。例如,可以通过创建切面类并在目标类上添加注解来记录方法调用信息,从而在不侵入原有代码的情况下增强应用功能,提高代码的可维护性和可扩展性。
291 1