700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > springAOP中的target this within的区别

springAOP中的target this within的区别

时间:2023-06-26 00:26:27

相关推荐

springAOP中的target this within的区别

前言

关于这三者的区别,在网上找到的资料不多,大多是AspectJ的资料,并且大量的copy,查阅官方文档后,自己又做了一些实验,最终有了这篇博客,因为是自己摸索的结果,并且没有阅读相应源码,如有错误,欢迎指出(有空还是把markdown给看了,csdn的排版不是很喜欢...........

target

target匹配目标对象的类型,即被代理对象的类型,例如A继承了B接口,则使用target("B"),target("A")均可以匹配到A

this

this匹配的是代理对象的类型,例如存在一个接口B,使用this("B"),如果某个类A的JDK代理对象类型为B,则A实现的接口B的方法会作为切点进行织入。

this的匹配结果和最终生成的代理对象互不干涉,对于this(M),当M为类时,若一个类的CGLIB代理类型为M,该类的所有方法作为连接点织入到CGLIB代理对象中,当M为接口时,若一个类的JDK代理类型为M,该类实现的接口方法作为连接点织入JDK代理对象中,this的匹配结果不会影响spring生成代理对象的方式,若一个类继承了接口,则使用JDK代理,否则使用CGLIB代理,这就会出现下列情况:

A继承了B接口,this("A")会匹配到A的CGLIB代理,接着将A的所有方法织入到A的CGLIB代理对象中,但是因为A继承了B接口,所以spring

生成的是JDK代理对象,并不会因为this("A")的存在而生成CGLIB代理,我们来看一个例子:

项目结构:

Roleinterface:

package com.springdemo3;public interface Roleinterface {void print();}

Roleimplement:

package com.springdemo3;public class Roleimplement implements Roleinterface{public void print() {System.out.println("this is AOP");}}

AOP切面

import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;@Aspectpublic class AOP {@Pointcut("this(com.springdemo3.Roleimplement)")public void print() {};@Before("print()")public void beforeprint() {System.out.println("这是前置方法");}@After("print()")public void afterprint() {System.out.println("这是后置方法");}@AfterReturning("print()")public void afterreturning() {System.out.println("正常返回");}@AfterThrowing("print()")public void afterthrowing() {System.out.println("异常防护");}}

通过CGLIB匹配,会决定将Roleimplement的所有方法织入到CGLIB代理中,但是Roleimplement继承了接口,所以生成的是JDK代理,此时不会有方法被拦截

configurations类(配置类):

package com.springdemo3;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.EnableAspectJAutoProxy;import org.springframework.context.annotation.Bean;@Configuration@EnableAspectJAutoProxypublic class configurations {@Beanpublic Roleimplement getRoleinplement() {return new Roleimplement();}@Beanpublic AOP getAOP() {return new AOP();}}

App类(运行类)

package com.springdemo3;import org.springframework.context.ApplicationContext;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/****/public class App {public static void main( String[] args ){ApplicationContext ctx = new AnnotationConfigApplicationContext(configurations.class);Roleinterface temp=(Roleinterface)ctx.getBean(Roleinterface.class);temp.print();}}

结果:

为了证明生成的是JDK代理,通过设置断点查看

如果我们强制spring使用CGLIB代理:

在springdemo3.xml文件中设置:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xsd/schema/context /schema/context/spring-context.xsd/schema/aop /schema/aop/spring-aop-3.0.xsd"xmlns:p="/schema/p"xmlns:context="/schema/context"xmlns:aop="/schema/aop"><context:annotation-config/><aop:config proxy-target-class="true"/></beans>

xml中的某些命名空间是可以去掉,最重要的是加上<context:annotation-config/>

在@Configuration中使用注解:

@ImportResource("springdemo3.xml")

运行结果:

设置断点查看:

within

within比较严格,它是严格匹配被代理对象类型的,不会理会继承关系,例如A继承了接口B,则within("B")不会匹配到A,但是within("B+")可以匹配到A

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。