一AOP 联盟通知类型
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();
}
}