spring aop的另外一种实现
来源:互联网 发布:travel域名 编辑:程序博客网 时间:2024/05/18 03:52
在了解了基本的理论之后,我们通过一个实例来强化对AOP的认识。我们希望通过一个自定义的Aspect,来为业务方法添加上基本的debug信息和调用时间的记录。其主要思路是:通过定义业务接口,在业务接口的方法上(Joinpoint)添加该Aspect。在实现Aspect上,我们使用最常用的Interception。有了这个思路之后,我们先进行准备工作,先定义业务接口,并实现业务方法:
public interface SearchBookBean {
public void search();
}
public class SearchBookBeanImpl implements SearchBookBean{
public void search()
{
System.out.println("Business iethod s Called");
}
}
然后是最重要的事情,定义一个拦截器,拦截器需要符合AOP Alliance的规范:
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MyInterceptor implements MethodInterceptor
{
private final Log logger = LogFactory.getLog(getClass());
public Object invoke(MethodInvocation methodInvocation) throws Throwable
{
logger.info("Beginning method: " + methodInvocation.getMethod().getDeclaringClass() + "::" + methodInvocation.getMethod().getName());
long startTime = System.currentTimeMillis();
try
{
Object retVal = methodInvocation.proceed();
return retVal;
}
finally
{
logger.info("Ending method: " +
methodInvocation.getMethod().getDeclaringClass() + "::" +
methodInvocation.getMethod().getName());
logger.info("Method invocation time: " + (System.currentTimeMillis() - startTime) + " msecs.");
}
}
}
主要的工作都已经做完了,上面的代码中,最重要的两句代码已经加粗表示了,它表示当前的拦截器处理完成后,将控制权交给下一个拦截器。从拦截器的结构来看,我们前面所说拦截器能够实现所有的Aspect功能的话是对的。
然后,我们需要通过配置文件把这些bean组合起来:
<beans>
<bean id="SearchBookBeanTarget" class="SearchBookBeanImpl" />
<bean id="myInterceptor" class="MyInterceptor" />
<bean id="SearchBookBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>SearchBookBean</value></property>
<property name="interceptorNames">
<list>
<value>myInterceptor</value>
<value>SearchBookBeanTarget</value>
</list>
</property>
</bean>
</beans>
首先,定义一个具体的目标bean-SearchBookBeanTarget,然后,声明一个拦截器-myInterceptor。接下来,就需要将拦截器和目标bean关联起来,这里使用到了ProxyFactoryBean,我们先不管它的具体实现,只要知道它起到一个连接器的作用,所以,它的参数中应该包括到拦截器和目标bean的引用。
我们先不管配置文件的具体含义。先来看看最终的调用代码:
public static void main(String[] args) {
InputStream is = Spike.class.getClassLoader().getResourceAsStream("aop.xml");
SearchBookBean sbb=(SearchBookBean)new XmlBeanFactory(is).getBean("SearchBookBean");
sbb.search();
}
然后是输出结果:
Debug interceptor: count=1 invocation=[Invocation:
method=[public abstract void SearchBookBean.search()]
args=null] target is of class SearchBookBeanImpl]
Search Service is Called
Debug interceptor: next returned
额外的功能已经添加到接口的方法上了,而接口和实现本身都没有任何的相关代码。看起来十分神奇,那么我们现在就分析一下它的原理。
LOG
通过分析spring的log,我们可以了解上面的例子到底做了些什么:
14:04:30,338 DEBUG ProxyFactoryBean:265 - Added new aspect interface: interface SearchBookBean
14:04:30,338 DEBUG ProxyFactoryBean:126 - Set BeanFactory. Will configure interceptor beans...
14:04:30,338 DEBUG ProxyFactoryBean:160 - Configuring interceptor 'myInterceptor'
14:04:30,338 INFO XmlBeanFactory:187 - Creating shared instance of singleton bean 'myInterceptor'
14:04:30,348 DEBUG ProxyFactoryBean:255 - Adding advisor or TargetSource [MyInterceptor@2f1921]
with name [myInterceptor]
14:04:30,368 DEBUG ProxyFactoryBean:261 - Adding advisor with name [myInterceptor]
14:04:30,368 DEBUG ProxyFactoryBean:160 - Configuring interceptor 'SearchBookBeanTarget'
14:04:30,368 INFO XmlBeanFactory:187 - Creating shared instance of singleton bean 'SearchBookBeanTarget'
14:04:30,378 DEBUG ProxyFactoryBean:255 - Adding advisor or TargetSource [SearchBookBeanImpl@10bc49d]
with name [SearchBookBeanTarget]
14:04:30,378 DEBUG ProxyFactoryBean:271 - Adding TargetSource [Singleton target source (not dynamic):
target=[SearchBookBeanImpl@10bc49d]] with name [SearchBookBeanTarget]
14:04:30,378 INFO ProxyFactoryBean:128 - ProxyFactoryBean config:
14:04:30,388 DEBUG JdkDynamicAopProxy:177 - Creating JDK dynamic proxy
以上的log做了大量的简化,但已经足够说明问题了。最核心的对象是ProxyFactoryBean,也就是配置文件中定义的,以及我们最终使用的那个对象。它的本质是一个基于类的适配器。它将AOP的具体实现转换为一个标准的,符合spring配置规范的bean。这样,除了使用AOP的功能之外,还可以使用配置来管理该对象。所以,该对象是我们研究的重点。
在范例的配置文件中,ProxyFactoryBean有两组的参数,一个是proxyInterfaces,它代表需要被代理的接口,也就是我们希望在哪个接口上添加功能。另一个是interceptorNames。它是一个列表,代表有几种的意思,一是需要添加到目标接口的Advice,如debugInterceptor,二是真正的实现对象,如SearchBookBeanTarget,称为TargetSource。前者可以有多个的,但后者只能有一个。
所以上述log文件除最后一行外,都是在对ProxyFactoryBean的各个属性进行配置。其中,最核心的处理是ProxyFactoryBean实现BeanFactoryAware接口的setBeanFactory回调方法。在这个方法中,ProxyFactoryBean将文本的配置信息转换为真正的对象,并进行配置。ProxyFactoryBean同时还是一个FactoryBean。因此,它可以不返回自身,而通过getObject方法返回一个自身的代理。这样,对接口本身的调用都转换为对代理对象的调用。而代理对象会在调用真正的方法的前后调用一些额外的方法。
在spring中,代理对象的实现采用了两种形式,一种是基于JDK1.3提供的proxy机制,一种是基于开源软件CGLIB提供的代理机制。
- spring aop的另外一种实现
- 指数函数的另外一种实现
- 【Hello World】的另外一种实现方法
- vibe算法的另外一种实现
- ffs的另外一种实现方法
- 同步锁的另外一种实现
- RecyclerView 实现点击的另外一种方式
- CXF实现用户验证(相比前面的另外的一种方法完全Spring)
- Spring AOP的八个概念、五个通知类型、AOP的第一种实现方式
- Spring的AOP实现
- Spring AOP的实现
- spring的aop实现
- Spring AOP 的实现
- Spring--AOP的实现
- Spring AOP的实现
- Spring Aop的实现
- spring的aop实现
- spring-AOP的实现
- java面试题[其他类]
- 各厂家内存编号的含义
- 减少文件之间的编译依赖
- Spring AOP处理日志
- 什么是Web 2.0?
- spring aop的另外一种实现
- ajax in action——javascript面向对象编程(上)
- 取得远程文件并保存到本地
- Spring aop实现事务加锁
- Learn Linux
- 关于C++指针的研究
- Struts处方:Hibernate与Struts
- Spring AOP实现权限的管理
- 博客文章该使用什么样的版权呢?