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

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 {
	@Override
	public 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;
@Configuration
public class AppConfig{
	@Bean
	public UserService userServiceImpl(){
		return new UserServiceImpl();
	}
	@Bean
	public Advice debugInterceptor(){
		return new DebugInterceptor();
	}
	@Bean
	public 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来定义一个切面.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值