1.AOP及Spring AOP背景知识
Spring AOP由100% java开发完成,秉承java的一切优势。
目前,Spring AOP只实现了方法级的joinpoint,有些AOP实现支持域级的joinpoint,比如JBoss AOP、AspectJ。joinpoint(连接点模型)是指AOP Aspect能够在应用系统中执行的地方,比如某个方法调用之前、修改某个域之前。连接点模型的强弱在很大程度上决定了AOP实现功能的强弱。
尽管Spring也能够用于J2SE、J2ME应用,但主要是在J2EE应用中使用它(Spring team推荐如此)。在J2EE应用中,AOP能够拦截到方法集的操作已经足够了。再者,OOP倡导的是通过setter/getter方法访问域,而不是直接访问域。因此目前Spring仅提供方法级的joinpoint是恰当的。
借助于Spring AOP,Spring Ioc能方便的使用到非常健壮、灵活的企业级服务。Spring AOP能够提供如下几方面的优势:
1)允许开发者使用声明式企业级服务,比如事务服务、安全性服务。
2)开发者可以开发满足业务需求的自定义方面。如果标准的J2EE安全性不满足业务需求,则必须开发拦截器。
3)开发Spring AOP Advice很方便。因为这些AOP Advice仅仅是POJO类,借助于Spring提供的ProxyFactoryBean,能够快速搭建Spring AOP Advice。
为开发AOP使能应用,需要开发AOP Advice,这是AOP开发的主要内容。因为advice中包含了AOP aspect的主要逻辑。
将AOP中的advice约定为“装备”。通常存在如下5种装备(Advice)类型:
1)Before装备:在执行目标操作之前执行的装备;
2)Throws装备:如果目标操作在执行过程中抛出异常,则执行此装备;
3)After装备:在执行目标操作之后执行的操作;
4)Around装备:在方法调用前后执行的装备;功能强大,灵活性也最好,能够在执行目标操作前后执行,因此这对于一些需要做资源初始化和释放资源的操作的应用而言,特别有用。
5)Introduction装备:由于Introduction装备能为类新增方法,因此在5中装备中,它最复杂,最难掌握。
借助于上述5种装备,基本能解决J2EE中的常见问题。
2.Spring AOP装备
对于Spring AOP而言,开发者会涉及到如下接口:
org.springframework.aop.MethodBeforeAdvice 用于实现Before装备;
org.springframework.aop.AfterReturningAdvice 用于实现After装备;
org.springframework.aop.ThrowsAdvice 用于实现Throws装备;
借助于RegexpMethodPointcutAdvisor类实现了对LoggingBeforeAdvice(此类为精通Spring源代码中example5中的类,实现了MethodBeforeAdvice接口,实现了其他装备接口的类集成方法类似)装备的集成,完成了pointcut和拦截器的定义。
Spring AOP由纯Java开发,开发者不需要对配置了装备的任何类进行编译工作。由于Spring AOP没有采用控制类装载器的方式来实现AOP,因此Spring AOP能使用与任何web容器应用服务器中,比如tomcat和Jboss。对于代理java接口的场景,Spring默认是采用动态代理实现的;对于代理java类的场景,Spring使用了动态字节码生成技术。
使用Spring AOP实现的各种装备类型时,ProxyFactoryBean起了很重要的作用(位于appcontext.xml)。
同其他Spring FactoryBean实现一样,ProxyFactoryBean也引入了间接层。需注意,通过名字或者id(比如,“helloworldbean”)获得的引用对象并不是ProxyFactoryBean实例本身,而是ProxyFactoryBean中getObject()方法实现返回的对象。其中,getObject方法将创建AOP代理,并将目标对象包裹(wrapper)在其中。代码示例:
Resource resource = new ClassPathResource("appcontext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
IHelloWorld hw = (IHelloWorld) factory.getBean("helloworldbean");
配置文件中的内容为:
<bean id="helloworldbean"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.openv.spring.IHelloWorld</value>
</property>
<property name="target">
<ref local="helloworldbeanTarget"/>
</property>
<property name="interceptorNames">
<list>
<value>loggingAfterAdvisor</value>
</list>
</property>
</bean>
开发者也可以借助于Spring AOP手工创建AOP代理。因此,这将不会依赖于Spring Ioc容器,而只是Spring AOP本身。不过不推荐这么使用,它不符合Spring框架的初衷。
Spring开发框架Team推荐:借助于Spring Ioc框架自动创建AOP代理,并将有关AOP代理的java代码通过Spring配置文件配置。
另外,FactoryBean在Spring框架中起了很重要的作用。ProxyFactoryBean实现了FactoryBean接口,借助于ProxyFactoryBean的强大功能,开发者能够实现满足各种业务需求的实现。但这要求开发者去额外开发很多辅助业务操作的功能,比如事务、数据库连接等操作。因此,Spring框架针对具体方面提供了大量的实用类(注意,它们并不是继承于ProxyFactoryBean,而是实现了FactoryBean接口):
TransactionProxyFactoryBean,SimpleRemoteStatelessSessionProxyFactoryBean,RmiProxyFactoryBean,LocalStatelessSessionProxyFactoryBean
3.对象池
开发者在与数据库交互的过程中,通常会使用到连接池。它能够在应用实际使用数据库连接前,同目标RDBMS建立物理连接。Spring框架借助于Jakarta Commons Pool或者其他技术,提供有效的对象池实现。