AOP半自动编写:
所谓半自动编写就是spring容器自动为我们生成代理对象,由我们手动获取代理对象。
环境搭建
1.接口(目标类)
2.切面类
3.spring容器
4.测试类
具体代码
接口代码
package com.fxy.study.aop;
public interface UserService {
public void addUser();
public void updateUser();
public void deleteUser();
}
切面类代码:
这里需要注意的是需要实现一个MethodInterceptor接口,并重写invoke方法,将增强代码写在其中。mi.proceed()方法即jdk代码中的method.invoke();
package com.fxy.study.aop;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAspect implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// TODO Auto-generated method stub
System.out.println("这是前方法");
Object obj = mi.proceed();
System.out.println("这是后方法");
return obj;
}
}
编写spring容器:
首先获取目标类和切面类的实例对象。
然后通过ProxyFactoryBean获取代理对象。
再将属性注入代理对象里。这里需要注入三个属性,一个目标类接口,一个目标类实例,用ref,一个切面类实例,用value,这个地方得注意。
<bean id="UserServiceId" class="com.fxy.study.aop.UserServiceImp"></bean>
<bean id="MyAspectId" class="com.fxy.study.aop.MyAspect"></bean>
<bean id="MyProxyId" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="interfaces" value="com.fxy.study.aop.UserService"></property>
<property name="target" ref="UserServiceId"></property>
<property name="interceptorNames" value="MyAspectId"></property>
</bean>
测试类:这里获取的是代理对象,MyProxyId
package com.fxy.study.aop;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAop {
@Test
public void demo04() {
String xmlPath = "com/fxy/study/aop/halfauto.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("MyProxyId");
userService.addUser();
userService.updateUser();
userService.deleteUser();
}
}
AOP编程:
这里将生成和获取代理对象的任务全交给spring容器去做,我们直接获取目标类的实例就行。
环境搭建:
环境与上面的差不多,只需要改spring xml文件和测试文件。
代码如下:
aop.xml
这里使用了aop编程,所有的东西全都放在aop-config中。
pointcut表示切入点,一般就是目标类所在的方法。
advisor表示通知,后面的两个属性分别表示advice-ref为增强代码的引用,即切点。pointcut-ref表示切入点的引用。
<bean id="UserServiceId" class="com.fxy.test.aop.UserServiceImp"></bean>
<bean id="MyAspectId" class="com.fxy.test.aop.MyAspect"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.fxy.test.aop.*.*(..))" id="pointcutId"/>
<aop:advisor advice-ref="MyAspectId" pointcut-ref="pointcutId"/>
</aop:config>
测试:
测试的地方只需要将获取bean的位置直接获取目标类的名称即可。