1、aop 联盟为通知advice定义了org.aopalliance.aop.Advice
2 、Spring 按照通知Advice 在目标类方法中的连接点位置,可以分为5类
前置通知 ....aop.MethodBeforeAdvice 在目标方法前实施增强
后置通知 ...aop.AfterReturningAdvice 在目标方法执行后实施增强
环绕通知 ......aop.MethodInterceptor (Interceptor:[ˌɪntərˈseptə(r)] )
在目标方法执行前后实施增强
异常抛出通知....aop.ThrowsAdvice 在哪方法抛出异常后实行增强
引介通知:aop.ItroductionInterceptor 在目标类中增加方法或者属性
演示环绕通知 环绕通知必须手动执行目标方法
try{
//前置通知
执行目标方法
//后置通知
} catch(){}
1 让spring创建代理对象,从spring容器中手动的获得代理对象
2 导入jar包
spring核心 :4+1
aop aop联盟规范 :com.springsource.org.aopalliance-1.0.0.jar
3 :目标类
//接口public interface IUserService { public void addUser(); public void updateUser(); public void deleteUser();}
//实现类
public class UseServiceImpl implements IUserService { public void addUser() { System.out.println("增加用户的方法"); } public void updateUser() { System.out.println("更改用户的方法"); } public void deleteUser() { System.out.println("删除用户的方法"); }
}
//代理类
/** * 切面类中确定通知,需要实现不同接口,接口就是规范,从而就确定方法名称。 * 采用环绕通知 实现 MethodInterceptor 接口 * @author dukun * */public class MyAspectBean implements MethodInterceptor{ public Object invoke(MethodInvocation mi) throws Throwable { System.out.println("advice前置通知"); // TODO Auto-generated method stub //手动执行目标方法 Object obj=mi.proceed(); System.out.println("advice后置通知"); return obj; }}
//bean.xml配置
<?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:p="http://www.springframework.org/schema/p" 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="userService" class="com.nari.service.impl.UseServiceImpl"></bean> <!-- 创建切面类 --> <bean id="myAspectBean" class="com.nari.bean_factory.MyAspectBean"></bean> <!--3创建代理类 *使用工厂BEAN FactoryBean,底层调用getObject()返回特殊bean *ProxyFactoryBean 用于创建代理工厂bean,生成特殊的代理对象 interfaces:确定接口门 通过<array>可以设置多个值 target:确定目标类 **** interceptorNames:通知的切面类的名称,类型String[],如果设置一个值是value="" 一个不是必填的属性 optimize:强制使用CGLIB <property name="optimize" value="true"></property> ** 底层机制 如果目标类有接口,采用Jdk动态代理 如果没有接口,采用CGLIB字节码增强 如果 使用<property name="optimize" value="true"></property> 都采用CGLIB字节码增强 --> <bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="interfaces" value="com.nari.service.IUserService"></property> <property name="target" ref="userService"></property> <property name="interceptorNames" value="myAspectBean"></property> </bean>
</beans>
测试:
public class FactoryBeanTest { @Test public void test2(){ String xmlPath = "applicationContext.xml"; ApplicationContext appliactionContext =new ClassPathXmlApplicationContext(xmlPath); IUserService userService = (IUserService) appliactionContext.getBean("proxyService"); userService.addUser(); }}