前置增强

/ Spring / 没有评论 / 288浏览

在上一篇中我们已经通过了动态代理技术实现了简单的AOP功能,但是如果我们细心观察就会发现,通过上一篇中的方式实现有,几点明显需要改进的地方,它们分别是:

要想解决上述问题,解决的办法就是使用spring为我们提供的增强,在其它文章中我们已经介绍过了增强就是添加到目标类特殊连接点的信息,并且spring为我们提供了的增强都在带方位信息的,也就是在方法前、方法后等。所以我们可以很方便的使用增强来使我们需要添加事物的方法动态添加织入的功能。下面我们将演示,spring中为我们都提供了哪些增强。

顾名思义也就是在目标方法执行之前添加横切的逻辑。我们通过下面的用例来演示一下前置增强的具体使用。

public class TransactionManager {
public static void beginTransaction() {
System.out.println("开启事物");
}
public static void commit() {
System.out.println("提交事物");
}
}
public class UserServiceBeforeAdvice implements MethodBeforeAdvice{

@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("spring增强");
TransactionManager.beginTransaction();
}
}
@Test
public void test() {
IUserService target = new UserServiceImpl();
BeforeAdvice advice = new UserServiceBeforeAdvice();

ProxyFactory factory = new ProxyFactory();
factory.setTarget(target);
factory.addAdvice(advice);
IUserService userService = (IUserService) factory.getProxy();
userService.login("admin","jilinwula");
userService.register("admin","吉林乌拉","jilinwula");
}
spring增强
开启事物
用户登陆: username: admin password: jilinwula
spring增强
开启事物
用户注册: username: admin nickName: 吉林乌拉 password: jilinwula

我们知道spring中的AOP功能底层也是通过JDK动态代理或者使用CGLib动态代理,那么我们上述代码到底是通过哪种技术实现的呢?别着急我们看一下ProxyFactory类的底层实现。在ProxyFactory类中我们可以通过设置setInterfaces方法指定使用JDK动态代理。如果是对类进行代理,因为JDK代理不支持,所以ProxyFactory就会采用CGLib动态代理。我们还可以通过setOptimize方法来让ProxyFactory启动优化方式,这样,即使是对接口进行代理,也会使用CGLib代理。

JDK动态代理

@Test
public void test() {
IUserService target = new UserServiceImpl();
BeforeAdvice advice = new UserServiceBeforeAdvice();

ProxyFactory factory = new ProxyFactory();
factory.setInterfaces(target.getClass().getInterfaces());
factory.setTarget(target);
factory.addAdvice(advice);
IUserService userService = (IUserService) factory.getProxy();
userService.login("admin","jilinwula");
userService.register("admin","吉林乌拉","jilinwula");
}

CGLib动态代理

@Test
public void test() {
IUserService target = new UserServiceImpl();
BeforeAdvice advice = new UserServiceBeforeAdvice();

ProxyFactory factory = new ProxyFactory();
factory.setInterfaces(target.getClass().getInterfaces());
factory.setOptimize(true);
factory.setTarget(target);
factory.addAdvice(advice);
IUserService userService = (IUserService) factory.getProxy();
userService.login("admin","jilinwula");
userService.register("admin","吉林乌拉","jilinwula");
}

下面我们通过sping配置文件的方式实现AOP动态代理功能。

<bean id="userServiceAdvice" class="com.jilinwula.spring.aop.UserServiceBeforeAdvice"/>
<bean id="target" class="com.jilinwula.spring.aop.UserServiceImpl"/>
<bean id="userService" class="org.springframework.aop.framework.ProxyFactoryBean"
p:proxyInterfaces="com.jilinwula.spring.aop.IUserService"
p:interceptorNames="userServiceAdvice"
p:target-ref="target"/>
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
IUserService userService = applicationContext.getBean("userService", IUserService.class);
userService.register("admin","吉林乌拉","jilinwula");
}
spring增强
开启事物
用户注册: username: admin nickName: 吉林乌拉 password: jilinwula

下面我们看一下org.springframework.aop.framework.ProxyFactoryBean类的相关属性说明: