当前位置: 首页 > news >正文

网站建设酷万网络天天广告联盟

网站建设酷万网络,天天广告联盟,大型门户网站建设定制,湘潭市网站建设文章目录系列文档索引四、Spring AOP的使用入门1、激活AspectJ模块(1)注解激活(2)XML激活2、创建 AspectJ 代理(了解)(1)编程方式创建 AspectJ 代理实例(2)XM…

文章目录

  • 系列文档索引
  • 四、Spring AOP的使用入门
    • 1、激活AspectJ模块
      • (1)注解激活
      • (2)XML激活
    • 2、创建 @AspectJ 代理(了解)
      • (1)编程方式创建 @AspectJ 代理实例
      • (2)XML 配置创建 AOP 代理
      • (3)标准代理工厂 API
    • 3、Pointcut 使用
      • (1)Pointcut 指令与表达式
      • (2)XML 配置 Pointcut
      • (3)API 实现 Pointcut
    • 4、拦截动作
      • (1)注解方式实现
      • (2)XML配置方式实现
      • (3)API方式实现
      • (4)同一个@Before执行顺序
  • 未完待续
  • 参考资料

系列文档索引

SpringAOP从入门到源码分析大全,学好AOP这一篇就够了(一)
SpringAOP从入门到源码分析大全,学好AOP这一篇就够了(二)
SpringAOP从入门到源码分析大全,学好AOP这一篇就够了(三)
SpringAOP从入门到源码分析大全,学好AOP这一篇就够了(四)

四、Spring AOP的使用入门

1、激活AspectJ模块

激活AspectJ模块分两种方式,一种是使用注解方式,一种使用xml方式。

• 注解激活 - @EnableAspectJAutoProxy
• XML 配置 - <aop:aspectj-autoproxy/>

(1)注解激活

import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Aspect        // 声明为 Aspect 切面
@Configuration // Configuration class
@EnableAspectJAutoProxy // 激活 Aspect 注解自动代理
public class AspectJAnnotationDemo {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(AspectJAnnotationDemo.class);context.refresh();AspectJAnnotationDemo aspectJAnnotationDemo = context.getBean(AspectJAnnotationDemo.class);System.out.println(aspectJAnnotationDemo.getClass());context.close();}
}

以上是使用注解激活的实例,使用@EnableAspectJAutoProxy即可激活Aspect注解自动代理。

该AspectJAnnotationDemo类使用@Configuration标注代表是一个配置类,Spring中的配置类都会被代理,默认是使用CGLIB代理。

@Aspect表示该类是一个切面类。

(2)XML激活

在xml文件中使用该标签,即可激活Aspect自动代理:

<aop:aspectj-autoproxy/>

该标签与注解的@EnableAspectJAutoProxy效果相同。

2、创建 @AspectJ 代理(了解)

(1)编程方式创建 @AspectJ 代理实例

实现类: org.springframework.aop.aspectj.annotation.AspectJProxyFactory

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
import org.springframework.aop.framework.AopContext;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;public class AspectJAnnotationUsingAPIDemo {public static void main(String[] args) {// 通过创建一个 HashMap 缓存,作为被代理对象Map<String, Object> cache = new HashMap<>();// 创建 Proxy 工厂(AspectJ)AspectJProxyFactory proxyFactory = new AspectJProxyFactory(cache);// 增加 Aspect 配置类,暂时不需要
//        proxyFactory.addAspect(AspectConfiguration.class);// 设置暴露代理对象到 AopContextproxyFactory.setExposeProxy(true);proxyFactory.addAdvice(new MethodBeforeAdvice() {@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {if ("put".equals(method.getName()) && args.length == 2) {Object proxy = AopContext.currentProxy();System.out.printf("[MethodBeforeAdvice] 当前存放是 Key: %s , Value : %s ," +"代理对象:%s\n", args[0], args[1], proxy);}}});// 添加 AfterReturningAdviceproxyFactory.addAdvice(new AfterReturningAdvice() {@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target)throws Throwable {if ("put".equals(method.getName()) && args.length == 2) {System.out.printf("[AfterReturningAdvice] 当前存放是 Key: %s , 新存放的 Value : %s , 之前关联的 Value : %s\n ",args[0],    // keyargs[1],    // new valuereturnValue // old value);}}});// 通过代理对象存储数据Map<String, Object> proxy = proxyFactory.getProxy();proxy.put("1", "A");proxy.put("1", "B");System.out.println(cache.get("1"));}
}

(2)XML 配置创建 AOP 代理

<aop:aspectj-autoproxy/><bean id="echoService" class="com.demo.DefaultEchoService"></bean><!--拦截器-->
<bean id="echoServiceMethodInterceptor"class="com.demo.interceptor.EchoServiceMethodInterceptor"/><bean id="echoServiceProxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="targetName" value="echoService"/> <!--指定targetName为需要代理的bean的Id--><property name="interceptorNames"> <!--指定拦截器--><value>echoServiceMethodInterceptor</value></property>
</bean>
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import java.lang.reflect.Method;public class EchoServiceMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {Method method = invocation.getMethod();System.out.println("拦截 EchoService 的方法:" + method);return invocation.proceed();}
}
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ClassPathXmlApplicationContext;@Aspect        // 声明为 Aspect 切面
@Configuration // Configuration class
public class ProxyFactoryBeanDemo {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:/META-INF/spring-aop-context.xml");EchoService echoService = context.getBean("echoServiceProxyFactoryBean", EchoService.class);System.out.println(echoService.echo("Hello,World"));System.out.println(echoService.getClass());context.close();}
}

我们发现,这种方式与编程的方式创建代理是差不多的,只不过是对象的创建交给Spring来处理了。

(3)标准代理工厂 API

实现类 - org.springframework.aop.framework.ProxyFactory

上面XML配置的方式创建ProxyFactoryBean,更多用于Spring中的应用,而ProxyFactory更偏底层。

import org.springframework.aop.framework.ProxyFactory;/*** ProxyFactory使用示例*/
public class ProxyFactoryDemo {public static void main(String[] args) {DefaultEchoService defaultEchoService = new DefaultEchoService();// 注入目标对象(被代理)ProxyFactory proxyFactory = new ProxyFactory(defaultEchoService);//proxyFactory.setTargetClass(DefaultEchoService.class);// 添加 Advice 实现 MethodInterceptor < Interceptor < AdviceproxyFactory.addAdvice(new EchoServiceMethodInterceptor());// 获取代理对象EchoService echoService = (EchoService) proxyFactory.getProxy();System.out.println(echoService.echo("Hello,World"));}
}
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import java.lang.reflect.Method;public class EchoServiceMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {Method method = invocation.getMethod();System.out.println("拦截 EchoService 的方法:" + method);return invocation.proceed();}
}

3、Pointcut 使用

Spring中的Pointcut只支持方法级别的定义,也就是说只支持Bean的方法拦截。

Pointcut 只是一个筛选,并没有具体的动作。
Advice才是具体的动作,一个Pointcut 可以对应多个Advice。

(1)Pointcut 指令与表达式

Spring AOP 之 aspect表达式详解

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;/*** Pointcut 示例*/
@Configuration // Configuration class
@EnableAspectJAutoProxy // 激活 Aspect 注解自动代理
public class AspectJAnnotatedPointcutDemo {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();context.register(AspectJAnnotatedPointcutDemo.class,AspectConfiguration.class);context.refresh();AspectJAnnotatedPointcutDemo aspectJAnnotationDemo = context.getBean(AspectJAnnotatedPointcutDemo.class);aspectJAnnotationDemo.execute();context.close();}public void execute() {System.out.println("execute()...");}
}
/*** Aspect 配置类*/
@Aspect
public class AspectConfiguration {@Pointcut("execution(public * *(..))") // 匹配 Join Pointprivate void anyPublicMethod() { // 方法名即 Pointcut 名System.out.println("@Pointcut at any public method."); // 方法通常设置为空的,不会有具体的动作}@Before("anyPublicMethod()")          // Join Point 拦截动作public void beforeAnyPublicMethod() {System.out.println("@Before any public method.");}}

Pointcut定义在切面类的私有方法上,该方法没有任何的动作,只是筛选要切入的方法。该方法名即为Pointcut名。

(2)XML 配置 Pointcut

<!--定义配置类-->
<bean id="aspectXmlConfig" class="com.demo.AspectXmlConfig"/><aop:config><aop:aspect id="AspectXmlConfig" ref="aspectXmlConfig"><!--引用配置类--><aop:pointcut id="anyPublicMethod" expression="execution(public * *(..))"/><!--Pointcut--><aop:before method="beforeAnyPublicMethod" pointcut-ref="anyPublicMethod"/><!--配置类的方法--></aop:aspect>
</aop:config>
public class AspectXmlConfig {public void beforeAnyPublicMethod() {System.out.println("@Before any public method.");}
}

(3)API 实现 Pointcut

核心 API - org.springframework.aop.Pointcut
• org.springframework.aop.ClassFilter
• org.springframework.aop.MethodMatcher

适配实现 - DefaultPointcutAdvisor

public static void main(String[] args) {EchoServicePointcut echoServicePointcut = new EchoServicePointcut("echo", EchoService.class);// 将 Pointcut 适配成 AdvisorDefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(echoServicePointcut, new EchoServiceMethodInterceptor());DefaultEchoService defaultEchoService = new DefaultEchoService();ProxyFactory proxyFactory = new ProxyFactory(defaultEchoService);// 添加 AdvisorproxyFactory.addAdvisor(advisor);// 获取代理对象EchoService echoService = (EchoService) proxyFactory.getProxy();System.out.println(echoService.echo("Hello,World"));
}
public class EchoServicePointcut extends StaticMethodMatcherPointcut {private String methodName;private Class targetClass;public EchoServicePointcut(String methodName, Class targetClass) {this.methodName = methodName;this.targetClass = targetClass;}@Overridepublic boolean matches(Method method, Class<?> targetClass) {return Objects.equals(methodName, method.getName())&& this.targetClass.isAssignableFrom(targetClass);}public String getMethodName() {return methodName;}public void setMethodName(String methodName) {this.methodName = methodName;}public Class getTargetClass() {return targetClass;}public void setTargetClass(Class targetClass) {this.targetClass = targetClass;}
}
public class EchoServiceMethodInterceptor implements MethodInterceptor {@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {Method method = invocation.getMethod();System.out.println("拦截 EchoService 的方法:" + method);return invocation.proceed();}
}

4、拦截动作

Around环绕动作。

Before前置动作。

After后置动作:
• 方法返回后:AfterReturning
• 异常发生后:AfterThrowing
• finally 执行:After

(1)注解方式实现

@Aspect
@Order
public class AspectConfiguration {@Pointcut("execution(public * *(..))") // 匹配 Join Pointprivate void anyPublicMethod() { // 方法名即 Pointcut 名System.out.println("@Pointcut at any public method.");}@Around("anyPublicMethod()")         // Join Point 拦截动作public Object aroundAnyPublicMethod(ProceedingJoinPoint pjp) throws Throwable {System.out.println("@Around any public method.");return pjp.proceed();}@Before("anyPublicMethod()")          // Join Point 拦截动作public void beforeAnyPublicMethod() {Random random = new Random();if (random.nextBoolean()) {throw new RuntimeException("For Purpose.");}System.out.println("@Before any public method.");}@After("anyPublicMethod()")public void finalizeAnyPublicMethod() {System.out.println("@After any public method.");}@AfterReturning("anyPublicMethod()")// AspectJAfterReturningAdvice is AfterReturningAdvice// 一个 AfterReturningAdviceInterceptor 关联一个 AfterReturningAdvice// Spring 封装 AfterReturningAdvice -> AfterReturningAdviceInterceptor// AfterReturningAdviceInterceptor is MethodInterceptor// AfterReturningAdviceInterceptor//  -> AspectJAfterReturningAdvice//      -> AbstractAspectJAdvice#invokeAdviceMethodWithGivenArgspublic void afterAnyPublicMethod() {System.out.println("@AfterReturning any public method.");}@AfterThrowing("anyPublicMethod()")public void afterThrowingAnyPublicMethod() {System.out.println("@AfterThrowing any public method");}public String toString() {return "AspectConfiguration";}private int getValue() {return 0;}
}

(2)XML配置方式实现

<aop:config><!--        <aop:pointcut id="allPointcut" expression="execution(* * *(..))"/>--><aop:aspect id="AspectXmlConfig" ref="aspectXmlConfig"><aop:pointcut id="anyPublicMethod" expression="execution(public * *(..))"/><aop:around method="aroundAnyPublicMethod" pointcut-ref="anyPublicMethod"/><aop:around method="aroundAnyPublicMethod" pointcut="execution(public * *(..))"/><aop:before method="beforeAnyPublicMethod" pointcut-ref="anyPublicMethod"/><aop:before method="beforeAnyPublicMethod" pointcut="execution(public * *(..))"/><aop:after method="finalizeAnyPublicMethod" pointcut-ref="anyPublicMethod"/><aop:after-returning method="afterAnyPublicMethod" pointcut-ref="anyPublicMethod"/><aop:after-throwing method="afterThrowingAnyPublicMethod" pointcut-ref="anyPublicMethod"/></aop:aspect>
</aop:config>
public class AspectXmlConfig {public Object aroundAnyPublicMethod(ProceedingJoinPoint pjp) throws Throwable {Random random = new Random();if (random.nextBoolean()) {throw new RuntimeException("For Purpose from XML configuration.");}System.out.println("@Around any public method : " + pjp.getSignature());return pjp.proceed();}public void beforeAnyPublicMethod() {System.out.println("@Before any public method.");}public void finalizeAnyPublicMethod() {System.out.println("@After any public method.");}public void afterAnyPublicMethod() {System.out.println("@AfterReturning any public method.");}public void afterThrowingAnyPublicMethod() {System.out.println("@AfterThrowing any public method.");}
}

(3)API方式实现

为什么 Spring AOP 不需要设计 Around Advice
• AspectJ @Around 与 org.aspectj.lang.ProceedingJoinPoint 配合执行被代理方法
• ProceedingJoinPoint#proceed() 方法类似于 Java Method#invoke(Object,Object…)
• Spring AOP 底层 API ProxyFactory 可通过 addAdvice 方法与 Advice 实现关联
• 接口 Advice 是 Interceptor 的父亲接口,而接口 MethodInterceptor 又扩展了 Interceptor
• MethodInterceptor 的invoke 方法参数 MethodInvocation 与 ProceedingJoinPoint 类似

API 实现 Before Advice

核心接口 - org.springframework.aop.BeforeAdvice

类型:标记接口,与 org.aopalliance.aop.Advice 类似

方法 JoinPoint 扩展 - org.springframework.aop.MethodBeforeAdvice

接受对象 - org.springframework.aop.framework.AdvisedSupport
• 基础实现类 - org.springframework.aop.framework.ProxyCreatorSupport
• 常见实现类:org.springframework.aop.framework.ProxyFactory;org.springframework.aop.framework.ProxyFactoryBean;org.springframework.aop.aspectj.annotation.AspectJProxyFactory

API 实现三种 After Advice

核心接口 - org.springframework.aop.AfterAdvice

类型:标记接口,与 org.aopalliance.aop.Advice 类似

扩展
• org.springframework.aop.AfterReturningAdvice
• org.springframework.aop.ThrowsAdvice

接受对象 - org.springframework.aop.framework.AdvisedSupport
• 基础实现类 - org.springframework.aop.framework.ProxyCreatorSupport
• 常见实现类:org.springframework.aop.framework.ProxyFactory;org.springframework.aop.framework.ProxyFactoryBean;org.springframework.aop.aspectj.annotation.AspectJProxyFactory

// 通过创建一个 HashMap 缓存,作为被代理对象
Map<String, Object> cache = new HashMap<>();
// 创建 Proxy 工厂(AspectJ)
AspectJProxyFactory proxyFactory = new AspectJProxyFactory(cache);
// 增加 Aspect 配置类,此处不需要
// proxyFactory.addAspect(AspectConfiguration.class);
// 设置暴露代理对象到 AopContext
proxyFactory.setExposeProxy(true);
proxyFactory.addAdvice(new MethodBeforeAdvice() {@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {if ("put".equals(method.getName()) && args.length == 2) {Object proxy = AopContext.currentProxy();System.out.printf("[MethodBeforeAdvice] 当前存放是 Key: %s , Value : %s ," +"代理对象:%s\n", args[0], args[1], proxy);}}
});// 添加 AfterReturningAdvice
proxyFactory.addAdvice(new AfterReturningAdvice() {@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target)throws Throwable {if ("put".equals(method.getName()) && args.length == 2) {System.out.printf("[AfterReturningAdvice] 当前存放是 Key: %s , 新存放的 Value : %s , 之前关联的 Value : %s\n ",args[0],    // keyargs[1],    // new valuereturnValue // old value);}}
});// 通过代理对象存储数据
Map<String, Object> proxy = proxyFactory.getProxy();
proxy.put("1", "A");
proxy.put("1", "B");
System.out.println(cache.get("1"));

(4)同一个@Before执行顺序

注解驱动:使用@Order注解标注切面类,同一类中的顺序无法保证。

XML驱动:按照先后顺序执行。

未完待续

参考资料

极客时间《小马哥讲 Spring AOP 编程思想》


文章转载自:
http://wanjiahymnologist.hwbf.cn
http://wanjiafick.hwbf.cn
http://wanjiasplack.hwbf.cn
http://wanjiasegue.hwbf.cn
http://wanjiamicrolitre.hwbf.cn
http://wanjiabuddhahood.hwbf.cn
http://wanjiakatie.hwbf.cn
http://wanjiandis.hwbf.cn
http://wanjiamarla.hwbf.cn
http://wanjiapond.hwbf.cn
http://wanjiainmesh.hwbf.cn
http://wanjialinsang.hwbf.cn
http://wanjiazinciferous.hwbf.cn
http://wanjianattierblue.hwbf.cn
http://wanjiawrangell.hwbf.cn
http://wanjiametacmpile.hwbf.cn
http://wanjiacarlsruhe.hwbf.cn
http://wanjiaastray.hwbf.cn
http://wanjianaperville.hwbf.cn
http://wanjiapajama.hwbf.cn
http://wanjiaaoudad.hwbf.cn
http://wanjiavotaress.hwbf.cn
http://wanjiaaeroelastic.hwbf.cn
http://wanjiarelaxation.hwbf.cn
http://wanjiacolombia.hwbf.cn
http://wanjiaconvalescent.hwbf.cn
http://wanjiabaskerville.hwbf.cn
http://wanjiaxylophonist.hwbf.cn
http://wanjiasailship.hwbf.cn
http://wanjiasomewhither.hwbf.cn
http://wanjiavaletta.hwbf.cn
http://wanjiareassurance.hwbf.cn
http://wanjiamegabuck.hwbf.cn
http://wanjiakineticist.hwbf.cn
http://wanjiaviolent.hwbf.cn
http://wanjiamome.hwbf.cn
http://wanjiasmash.hwbf.cn
http://wanjiavalidation.hwbf.cn
http://wanjiachronologer.hwbf.cn
http://wanjiarecitativo.hwbf.cn
http://wanjiaclicket.hwbf.cn
http://wanjiaromanian.hwbf.cn
http://wanjiaenactory.hwbf.cn
http://wanjiabejeaned.hwbf.cn
http://wanjiaswill.hwbf.cn
http://wanjiaencloud.hwbf.cn
http://wanjiawaterside.hwbf.cn
http://wanjiasoftball.hwbf.cn
http://wanjiavinyon.hwbf.cn
http://wanjiacrag.hwbf.cn
http://wanjiamica.hwbf.cn
http://wanjiamalfeasant.hwbf.cn
http://wanjiapneumatic.hwbf.cn
http://wanjiagorki.hwbf.cn
http://wanjiaase.hwbf.cn
http://wanjiacatenarian.hwbf.cn
http://wanjiastrudel.hwbf.cn
http://wanjiaroyally.hwbf.cn
http://wanjiabimetallic.hwbf.cn
http://wanjiasettling.hwbf.cn
http://wanjiasupposititious.hwbf.cn
http://wanjiarockery.hwbf.cn
http://wanjiadisarticulation.hwbf.cn
http://wanjiarumple.hwbf.cn
http://wanjiabeechen.hwbf.cn
http://wanjiasequestered.hwbf.cn
http://wanjiamolecast.hwbf.cn
http://wanjiahepatatrophia.hwbf.cn
http://wanjiamiff.hwbf.cn
http://wanjiaattain.hwbf.cn
http://wanjiawomanliness.hwbf.cn
http://wanjiaaudrey.hwbf.cn
http://wanjiaosteopathic.hwbf.cn
http://wanjiachristian.hwbf.cn
http://wanjiaunprofessional.hwbf.cn
http://wanjiabiparasitic.hwbf.cn
http://wanjiabenzoline.hwbf.cn
http://wanjiacrinum.hwbf.cn
http://wanjiagang.hwbf.cn
http://wanjiahasid.hwbf.cn
http://www.15wanjia.com/news/127725.html

相关文章:

  • 用php怎么做网站什么是指数基金
  • 做英文网站费用怎么接游戏推广的业务
  • WordPress不使用MySQL数据库深圳seo排名哪家好
  • 制作网站公司谁家好深圳创新创业大赛
  • 天津网上办事大厅优化大师win10
  • 服务器网站建设情况手机百度识图网页版入口
  • 网站建设费需要分摊吗推广平台怎么找客源
  • 电子商务网站建设的一般步骤有更先进的seo服务
  • 什么是网站域名?上海抖音seo公司
  • wordpress更改语言seo代码优化有哪些方法
  • 一个网站一个月发多少外链比较合适广州网站关键词推广
  • app开发公司杭州上海做网络口碑优化的公司
  • 网页制作与网站建设宝典扫描版pdf爱站网使用体验
  • 外部网站链接怎么做杭州seo建站
  • 做平面设计去哪个网站找素材好百度官网电话客服24小时
  • 对政府网站建设的意见建议seo网站排名优化快速排
  • 办公室装修图片seo关键词优化案例
  • 网站js下载seo排名优化点击软件有哪些
  • 济南网站制作0531soso无锡百姓网推广
  • in word in the wordpress微信小程序排名关键词优化
  • 虚拟网站建设步骤下载百度app最新版并安装
  • 中核华泰建设有限公司的网站佛山seo网站排名
  • 品牌网站建设的要点千锋教育怎么样
  • 室内设计接单网站如何seo网站推广
  • 医药公司网站建设嘉兴网站建设制作
  • 做网站有哪些类型的百度旧版本
  • 国内的优秀网站企业网络推广的方式有哪些
  • 深圳市住房和建设局官方网站查询网站搭建
  • 天河网站建设信科网络百度网盟推广官方网站
  • 仿站仿淘宝客网站视频教程视频剪辑培训班一般学费多少