spring aop(三)--aop在spring的使用

来源:互联网 发布:汇编语言 多维数组 编辑:程序博客网 时间:2024/05/19 02:00
spring使用aop
增强通知的种类:
a.前置通知:在执行目标方法前实施某种逻辑.
b.后置通知:在执行目标方法后实施某种逻辑.
c.环绕通知在执行目标方法前后实施某种逻辑.
d.异常抛出通知:在执行目标方法抛出异常实施某种逻辑.
e.引入通知:在执行目标类添加新方法和属性.


一.先从一个前置通知例子入手:
1.ForumService.java和ForumServiceImpl.java参考spring aop(一)--基于JDK

2.实现MethodBeforeAdvice接口的ForumBeforeAdvice来实现前置通知的业务逻辑,下面只是简单输出一句话,按下面使用,那么每次调用ForumServiceImpl的每个方法前都么输出这句话.

import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;public class ForumBeforeAdvice implements MethodBeforeAdvice {@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println("before advice:"+method);}}
3.测试使用
import org.springframework.aop.BeforeAdvice;import org.springframework.aop.framework.ProxyFactory;public class TestForumService {public static void main(String[] args) {ForumService target=new ForumServiceImpl();BeforeAdvice advice=new ForumBeforeAdvice();ProxyFactory proxyFactory=new ProxyFactory();//proxyFactory.setInterfaces(target.getClass().getInterfaces());//proxyFactory.setOptimize(true);proxyFactory.setTarget(target);proxyFactory.addAdvice(advice);ForumService proxy= (ForumService) proxyFactory.getProxy();proxy.removeForum(10);proxy.removeTopic(1012);}}
小结:spring到底使用基于jdk还是基于CGLib创建动态代理,取决于你的配置,按上面的配置是使用了ObjenesisCglibAopProxy来创建代理.至于详细,可进入org.springframework.aop.framework.DefaultAopProxyFactory.createAopProxy方法调试.


二.以上配置都是编程式来生成代理,可以将此代理实例注册成为spring的bean.以下是基于xml的applicationContext.xml声明式配置例子(基于java-config就简单得多了).
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">    <bean id="forumServiceImpl" class="org.exam.aop.ForumServiceImpl" />    <bean id="forumBeforeAdvice" class="org.exam.aop.ForumBeforeAdvice" />    <bean id="forumService" class="org.springframework.aop.framework.ProxyFactoryBean">        <property name="interfaces" value="org.exam.aop.ForumService" />        <property name="interceptorNames">            <list>                <value>forumBeforeAdvice</value>            </list>        </property>        <property name="target" ref="forumServiceImpl" />    </bean></beans>

基于java config的一个配置例子:

import org.aopalliance.aop.Advice;import org.exam.aop.DebugInterceptor;import org.exam.service.UserService;import org.exam.service.UserServiceImpl;import org.springframework.aop.framework.ProxyFactoryBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class AppConfig{@Beanpublic UserService userServiceImpl(){return new UserServiceImpl();}@Beanpublic Advice debugInterceptor(){return new DebugInterceptor();}@Beanpublic ProxyFactoryBean userService(){ProxyFactoryBean userService=new ProxyFactoryBean();userService.setInterceptorNames("debugInterceptor");userService.setTarget(userServiceImpl());return userService;}}

注册ProxyFactoryBean,要做两步:
1.定义使用的Advisor链(一系列Advisor Bean),并注入该Bean的interceptorNames属性.
2.定义要创建代理的Bean,并注入该Bean的target属性(可选:还有要创建代理Bean的接口名称注入该Bean的interfaces).

测试使用:

public class Main {    public static void main(String[] args) throws InterruptedException {        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");        ForumService proxy= (ForumService) applicationContext.getBean("forumService");        proxy.removeForum(10);        proxy.removeTopic(1012);    }}

直到目前为止,前面介绍的使用,横切逻辑都被织入了目标类的所有方法.下篇文章会介绍使用基于@AspectJ来定义一个切面.


0 0
原创粉丝点击