Spring研究之AOP初试
发布日期:2021-06-30 16:15:38
浏览次数:2
分类:技术文章
本文共 5955 字,大约阅读时间需要 19 分钟。
1、定义业务类接口
1 2 3 4 5 6 7 | package spring; public interface IStudent { void addStudent(String name); } |
2、业务实现类
1 2 3 4 5 6 7 8 9 10 | package spring; public class StudentServiceImpl implements IStudent{ public void addStudent(String name){ System.out.println( "add student operation name is" +name); } } |
3、前置通知
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package spring; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class BeforeAdvice implements MethodBeforeAdvice{ public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable { // TODO Auto-generated method stub System.out.println( "this is before method" ); } } |
4、后置通知
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | package spring; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class AfterAdvice implements AfterReturningAdvice { public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable { // TODO Auto-generated method stub System.out.println( "this is afterreturn method" ); } } |
5、环绕通知
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package spring; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class CompareInterceptor implements MethodInterceptor{ public Object invoke(MethodInvocation arg0) throws Throwable { // TODO Auto-generated method stub Object result= null ; String name=arg0.getArguments()[ 0 ].toString(); if (name!= null &&name.equalsIgnoreCase( "kerry" )) { result=arg0.proceed(); } else { System.out.println( "it is not kerry ,not permitted to join!" ); } return result; } } |
6、配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <?xml version= "1.0" encoding= "UTF-8" ?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" > <beans> <bean id= "beforeAdvice" class = "spring.BeforeAdvice" ></bean> <bean id= "afterAdvice" class = "spring.AfterAdvice" ></bean> <bean id= "compareInterceptor" class = "spring.CompareInterceptor" ></bean> <bean id= "studenttarget" class = "spring.StudentServiceImpl" ></bean> <bean id= "student" class = "org.springframework.aop.framework.ProxyFactoryBean" > <!--代理类的接口--> <property name= "proxyInterfaces" > <value>spring.IStudent</value> </property> <!--拦截器--> <property name= "interceptorNames" > <list> <value>beforeAdvice</value> <value>afterAdvice</value> <value>compareInterceptor</value> </list> </property> <!--业务实现类,逻辑代码--> <property name= "target" > <ref bean= "studenttarget" /> </property> </bean> </beans> |
7、测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package spring; import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class TestAOP { public static void main(String[] args) { ApplicationContext applicationContext= new FileSystemXmlApplicationContext( "src//spring/applicationContext.xml" ); IStudent student=(IStudent) applicationContext.getBean( "student" ); student.addStudent( "kerry" ); } } |
AOP分析:
1、AOP总体利用动态代理机制实现
2、<bean id="student" class="org.springframework.aop.framework.ProxyFactoryBean">定义代理类,代理类必须知道被代理类的信息,所以配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <bean id= "student" class = "org.springframework.aop.framework.ProxyFactoryBean" > <!--被代理类的接口--> <property name= "proxyInterfaces" > <value>spring.IStudent</value> </property> <!--拦截器--> <property name= "interceptorNames" > <list> <value>beforeAdvice</value> <value>afterAdvice</value> <value>compareInterceptor</value> </list> </property> <!--业务实现类,逻辑代码--> <property name= "target" > <ref bean= "studenttarget" /> </property> |
其中,属性的名称不可修改,对应ProxyFactoryBean的成员变量,以便在获取bean时,知道bean的接口(IStudent student=(IStudent) applicationContext.getBean("student"););如下源代码所示:
1 2 3 4 5 6 7 8 9 10 11 12 | /* */ public static final String GLOBAL_SUFFIX = "*" ; /* */ protected final Log logger; /* */ private String[] interceptorNames; /* */ private String targetName; /* */ private boolean autodetectInterfaces; /* */ private boolean singleton; /* */ private AdvisorAdapterRegistry advisorAdapterRegistry; /* */ private boolean freezeProxy; /* */ private transient ClassLoader beanClassLoader; /* */ private transient BeanFactory beanFactory; /* */ private boolean advisorChainInitialized; /* */ private Object singletonInstance; |
3、配置拦截器后,spring首先会检测该名称的bean是否被定义,如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | * */ private void checkInterceptorNames() /* */ { /* 363 */ if (!(ObjectUtils.isEmpty( this .interceptorNames))) { /* 364 */ String finalName = this .interceptorNames[( this .interceptorNames.length - 1 )]; /* 365 */ if (( this .targetName != null ) || ( this .targetSource != EMPTY_TARGET_SOURCE) || /* 368 */ (finalName.endsWith( "*" )) || (isNamedBeanAnAdvisorOrAdvice(finalName))) /* */ return ; /* 370 */ this .targetName = finalName; /* 371 */ if ( this .logger.isDebugEnabled()) { /* 372 */ this .logger.debug( "Bean with name '" + finalName + "' concluding interceptor chain " + "is not an advisor class: treating it as a target or TargetSource" ); /* */ } /* */ /* 375 */ String[] newNames = new String[ this .interceptorNames.length - 1 ]; /* 376 */ System.arraycopy( this .interceptorNames, 0 , newNames, 0 , newNames.length); /* 377 */ this .interceptorNames = newNames; /* */ } /* */ } |
4、通知最后被存储在List容器中
1 2 3 4 5 6 7 8 9 10 11 12 | /* */ public class AdvisedSupport extends ProxyConfig /* */ implements Advised /* */ { /* */ private static final long serialVersionUID = 2651364800145442165L; /* 70 */ public static final TargetSource EMPTY_TARGET_SOURCE = EmptyTargetSource.INSTANCE; /* */ TargetSource targetSource; /* */ private boolean preFiltered; /* */ AdvisorChainFactory advisorChainFactory; /* */ private transient Map methodCache; /* */ private List interfaces; /* */ <span style= "color:#ff0000;" > private List advisors; </span> /* */ private Advisor[] advisorArray; |
5、测试类中的student对象为代理对象,如图所示
转载地址:https://kerry.blog.csdn.net/article/details/42705517 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年05月02日 22时37分51秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
YbtOJ——字符串处理【例题1】数字反转
2019-04-30
转trt步骤记录
2019-05-01
MatConvNet安装
2019-05-01
依赖错误
2019-05-01
ROS安装与卸载
2019-05-01
安装openrave 0.9的各种依赖包
2019-05-01
trajopt代码使用
2019-05-01
kpm代码使用细节
2019-05-01
redis
2019-05-01
@FeignClient注解的重复名称解决
2019-05-01
ClassFile之Methods
2019-05-01
java.net.BindException: 无法指定被请求的地址
2019-05-01
scala list
2019-05-01
k8s设置阿里云仓库
2019-05-01
svn服务器安装
2019-05-01
spark 笔记1
2019-05-01
svn 没有作者信息) | (没有时间信息
2019-05-01
shell dirname basename
2019-05-01
线程分析
2019-05-01