Spring 传统AOP

内容纲要

## Spring AOP增强类型
1. AOP联盟为通知Advice定义了org.aopalliance.aop.Interface.Adive
2. Spring按照通知Adive在目标类方法的连接点位置,可以分为5类
1. 前置通知(MethodBeforeAdvice):在目标方法执行前实施增强
2. 后置通知(AfterReturningAdvice):在目标方法执行后实施增强
3. 环绕通知(MethodIntercepter):在目标方法执行前后实施增强
4. 异常通知(ThrowAdvice):在方法抛出异常后实施增强
5. (Spring只支持方法通知)引介通知(IntroductionIntercpter):在目标类中添加一些新的方法和属性

Spring AOP切面类型

  • Advisor:代表一般切面,Advice本身就是一个切面,对目标类所有方法进行拦截
  • PointcutAdvisor:代表具有切点的切面,可以指定拦截目标类那些方法
  • IntroductionAdvisor:代表引介切面,针对引介通知而使用切面

Advisor切面案列

==========Springdemo========
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo3 {
    // @Resource(name="studentDao")
    @Resource(name="studentDaoProxy")
    private StudentDao studentDao;
    @Test
    public void demo1(){
        studentDao.find();
        studentDao.save();
        studentDao.update();
        studentDao.delete();
    }
}
========StudentDao========
public interface StudentDao {
    public void find();
    public void save();
    public void update();
    public void delete();
}
========StudenDaoImpl========
public class StudentDaoImpl implements  StudentDao {
    public void find() {
        System.out.println("学生查询...");
    }
    public void save() {
        System.out.println("学生保存...");
    }
    public void update() {
        System.out.println("学生修改...");
    }
    public void delete() {
        System.out.println("学生删除...");
    }
}
========MyBeforeAdvice========
public class MyBeforeAdvice implements MethodBeforeAdvice {
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("前置增强======================");
    }
}
========XML========
<!--配置目标类=======================-->
<bean id="studentDao" class="Demo2.StudentDaoImpl"/>
<!--前置通知类型=====================-->
<bean id="myBeforeAdvice" class="Demo2.MyBeforeAdvice"/>
<!--Spring的AOP 产生代理对象-->
<bean id="studentDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <!--配置目标类-->
    <property name="target" ref="studentDao"/>
    <!--实现的接口-->
    <property name="proxyInterfaces" value="com.imooc.aop.demo3.StudentDao"/>
    <!--采用拦截的名称-->
    <property name="interceptorNames" value="myBeforeAdvice"/>
    <property name="optimize" value="true"></property>
</bean>

其他设置

  • proxyTargetClass:是否对类代理而不是接口,设置为ture时,使用CGLib代理
  • interceptorNames:需要织入目标的Advice
  • singleton:返回代理是否为单实例,默认为单例
  • optimize:当设置为ture时,强制使用CGLib代理

PointcutAdvisor切点切面

  1. 使用普通Adive作为切面,将对目标类所有方法进行拦截,不够灵活,在实际开发中常采用 带有切点的切面
  2. 常用PointcutAdvisor实现类
    • DefaultPointcutAdvisor最常见的切面类型,它可以通过任意Pointcut和Advice组合定义切面
    • JdkRegexpMethodPointcut 构造正则表达式切点
===========CustomeDao==========
public class CustomeDao {
    public void save() {
        System.out.println("保存客户....");
    }
    public void find() {
        System.out.println("查询客户....");
    }
    public void update() {
        System.out.println("修改客户....");
    }
    public void delete() {
        System.out.println("删除客户....");
    }
}
===========MyAroudAdvice==========
public class MyAroudAdvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation Invocation) throws Throwable {

        System.out.println("环绕前增强=======");
        Object obj = Invocation.proceed();
        System.out.println("环绕后增强=======");
        return obj;
    }
}
===========SpringDemo4==========
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:afterglow.xml")
public class SpringDemo4 {
//    @Resource(name = "customeDao")
    @Resource(name = "customeDaoProxy")
    private  CustomeDao customeDao;
    @Test
    public void demo1(){
        customeDao.save();
        customeDao.find();
        customeDao.update();
        customeDao.delete();
    }
}

===========afterglow.xml==========
<!--配置目标类============-->
<bean id="customeDao" class="Demo3.CustomeDao"></bean>
<!--配置通知============== -->
<bean id="myAroudAdvice" class="Demo3.MyAroudAdvice"></bean>
<!--一般的切面是使用通知作为切面的,因为要对目标类的某个方法进行增强就需要配置一个带有切入点的切面-->
<bean id="myAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    <!--pattern中配置正则表达式:.任意字符  *任意次数 -->
    <!--<property name="pattern" value=".*save.*"/>-->
    <property name="patterns" value=".*save.*,.*delete.*"/>
    <property name="advice" ref="myAroudAdvice"/>
</bean>
<!-- 配置产生代理 -->
<bean id="customeDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="customeDao"/>
    <property name="proxyTargetClass" value="true"/>
    <property name="interceptorNames" value="myAdvisor"/>
</bean>
THE END
分享
二维码
< <上一篇
下一篇>>