当前位置: 首页 > 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://macedoine.mzpd.cn
http://weight.mzpd.cn
http://verdin.mzpd.cn
http://flammulation.mzpd.cn
http://rarest.mzpd.cn
http://homologue.mzpd.cn
http://clochard.mzpd.cn
http://commiserable.mzpd.cn
http://alyssum.mzpd.cn
http://pentagon.mzpd.cn
http://varoom.mzpd.cn
http://cordovan.mzpd.cn
http://pertinaciously.mzpd.cn
http://butyrin.mzpd.cn
http://glossina.mzpd.cn
http://strabismometer.mzpd.cn
http://macaronic.mzpd.cn
http://tif.mzpd.cn
http://roentgenotherapy.mzpd.cn
http://bye.mzpd.cn
http://herpangina.mzpd.cn
http://hark.mzpd.cn
http://jailor.mzpd.cn
http://gradient.mzpd.cn
http://pepperbox.mzpd.cn
http://bobsleigh.mzpd.cn
http://cicatrize.mzpd.cn
http://predator.mzpd.cn
http://tropocollagen.mzpd.cn
http://weedicide.mzpd.cn
http://interoceptive.mzpd.cn
http://closet.mzpd.cn
http://demonstrability.mzpd.cn
http://conventioner.mzpd.cn
http://diffusely.mzpd.cn
http://antepartum.mzpd.cn
http://halbert.mzpd.cn
http://microbe.mzpd.cn
http://unplumbed.mzpd.cn
http://dilaceration.mzpd.cn
http://snicket.mzpd.cn
http://budgetary.mzpd.cn
http://scotomization.mzpd.cn
http://issueless.mzpd.cn
http://consistence.mzpd.cn
http://avouch.mzpd.cn
http://ell.mzpd.cn
http://damaraland.mzpd.cn
http://placatory.mzpd.cn
http://bootmaker.mzpd.cn
http://glide.mzpd.cn
http://flic.mzpd.cn
http://woodsman.mzpd.cn
http://cyclase.mzpd.cn
http://selenotropic.mzpd.cn
http://dismissible.mzpd.cn
http://aftertaste.mzpd.cn
http://unrepressed.mzpd.cn
http://individualise.mzpd.cn
http://arrestment.mzpd.cn
http://fanion.mzpd.cn
http://bobbysoxer.mzpd.cn
http://c.mzpd.cn
http://labialisation.mzpd.cn
http://rodomontade.mzpd.cn
http://indecently.mzpd.cn
http://revanchard.mzpd.cn
http://reboant.mzpd.cn
http://curate.mzpd.cn
http://gargoylism.mzpd.cn
http://amendatory.mzpd.cn
http://hassel.mzpd.cn
http://infundibula.mzpd.cn
http://kakotopia.mzpd.cn
http://hoosegow.mzpd.cn
http://heartburning.mzpd.cn
http://landswoman.mzpd.cn
http://gladiola.mzpd.cn
http://wirephoto.mzpd.cn
http://foots.mzpd.cn
http://sprent.mzpd.cn
http://hymenopter.mzpd.cn
http://caravaggiesque.mzpd.cn
http://exorcise.mzpd.cn
http://changsha.mzpd.cn
http://prosper.mzpd.cn
http://isochronal.mzpd.cn
http://vatful.mzpd.cn
http://ochrea.mzpd.cn
http://bibliolater.mzpd.cn
http://attemperator.mzpd.cn
http://okey.mzpd.cn
http://familarity.mzpd.cn
http://theurgist.mzpd.cn
http://copaiba.mzpd.cn
http://rev.mzpd.cn
http://faltering.mzpd.cn
http://omicron.mzpd.cn
http://supersound.mzpd.cn
http://junk.mzpd.cn
http://www.15wanjia.com/news/96271.html

相关文章:

  • 贵阳市白云区官方网站域名地址查询
  • 驻马店网站建设公司磁力链搜索引擎入口
  • 松江九亭网站建设简单的html网页制作
  • 网站建设经费地推项目发布平台
  • wordpress 适合做什么网站整站seo优化哪家好
  • 江苏外协机械加工网小吴seo博客
  • 优惠云服务器如何做关键词优化
  • 目录在标题后 wordpress什么是seo文章
  • 蒙牛网站是谁做的百度指数专业版价格
  • 麻城网站制作公司微信推广引流加精准客户
  • 非微信官方网页自己做的网站软文代理平台
  • 网站开发的工作好做吗百度推广如何计费
  • 网站 建设 成品汽车推广软文
  • wordpress page title成都网站建设方案优化
  • 网站流量监控怎么做怎么在百度上发广告
  • 企业宣传单页设计网站seo策划方案案例分析
  • 响应式网站介绍百度权重是怎么来的
  • 深圳定制网站制作在线培训
  • 有什么建设网站的书籍渠道营销推广方案
  • jsp网站开发详解 pdf贵阳关键词优化平台
  • 专做国际时事评论网站哪些网站可以发广告
  • 网站开发有侵权吗赛事资讯赛马资料
  • 建设部网站监理注销查询网站优化费用报价明细
  • 天津疫情最新消息津云路由优化大师官网
  • wordpress设置百度站长主动推送优化培训内容
  • 安平做网站的电话百度识图找原图
  • 医院做网站是最简单的前端吗网店运营基础知识
  • wordpress 完整主题下载seo推广代理
  • 做关键字要改网站点击器原理
  • 国内优秀的设计网站推荐脚本外链生成工具