AOP(2)

基于代理的AOP

1)jar包

spring
通常有cglib.jar足够了
通常有cglib足够了

2)接口

StudentDao .java

package com.dao;

public interface StudentDao {
public abstract void saveStudent();
public abstract void queryStudent();
}

3)接口的实现

StudentDaoImpl .java

package com.dao.impl;

import com.dao.StudentDao;

public class StudentDaoImpl implements StudentDao{

    @Override
    public void saveStudent() {
System.out.println("正在保存");     
    }

    @Override
    public void queryStudent() {
System.out.println("正在查询");     
    }

}

4)代理类

StudentDaoProxy .java

package com.proxy;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;

public class StudentDaoProxy implements MethodBeforeAdvice,AfterReturningAdvice{

    @Override
    public void afterReturning(Object arg0, Method arg1, Object[] arg2,
            Object arg3) throws Throwable {
System.out.println("after");        
    }

    @Override
    public void before(Method arg0, Object[] arg1, Object arg2)
            throws Throwable {
System.out.println("before");       
    }

}

5)xml配置

applicationContext.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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!--定义实现类bean  -->
<bean id="studentDaoImpl" class="com.dao.impl.StudentDaoImpl"/>
<!--定义代理类的bean  -->
<bean id="studentDaoProxy" class="com.proxy.StudentDaoProxy"></bean>
<!--定义切入点  -->
<bean id="studentDaoImplPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*Student"></property>
</bean>
<!--定义通知  -->
<bean id="studentDaoAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="studentDaoProxy"/>
<property name="pointcut" ref="studentDaoImplPointcut"/>
</bean>
<!--定义代理工厂  -->
<bean id="studentProxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="studentDaoImpl"/>
<property name="interceptorNames" value="studentDaoAdvisor"/>
<property name="proxyInterfaces" value="com.dao.StudentDao"/>
</bean>

</beans>

6)测试类

package com.proxy;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.dao.StudentDao;
import com.dao.impl.StudentDaoImpl;

import junit.framework.TestCase;

public class Test extends TestCase{
public void ProxyTest(){
    ApplicationContext ctx= new ClassPathXmlApplicationContext("applicationContext.xml");
    StudentDao studentDao=new StudentDaoImpl();
    studentDao=(StudentDao) ctx.getBean("studentProxyFactory");
    studentDao.saveStudent();
    studentDao.queryStudent();
}
}

自动代理的AOP

不在需要定义代理工厂

1)基于代理的AOP的 2)、3)、4)

2)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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!--定义实现类bean  -->
<bean id="studentDaoImpl" class="com.dao.impl.StudentDaoImpl"/>
<!--定义代理类的bean  -->
<bean id="studentDaoProxy" class="com.proxy.StudentDaoProxy"></bean>
<!--定义支持正则表达式的通知  -->
<bean id="studentDaoAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="studentDaoProxy"/>
<property name="pattern" value=".*Student"/>
</bean>

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>

<!--定义切入点 
<bean id="studentDaoImplPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="pattern" value=".*Student"></property>
</bean> -->
<!--定义通知 
<bean id="studentDaoAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="advice" ref="studentDaoProxy"/>
<property name="pointcut" ref="studentDaoImplPointcut"/>
</bean> -->
<!--定义代理工厂 
<bean id="studentProxyFactory" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="studentDaoImpl"/>
<property name="interceptorNames" value="studentDaoAdvisor"/>
<property name="proxyInterfaces" value="com.dao.StudentDao"/>
</bean> -->

</beans>

3)测试类

package com.proxy;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.dao.StudentDao;
import com.dao.impl.StudentDaoImpl;
public class TestProxy {
    @Test
public void ProxyTest(){
    ApplicationContext ctx= new ClassPathXmlApplicationContext("applicationContext.xml");
    StudentDao studentDao=new StudentDaoImpl();
    studentDao=(StudentDao) ctx.getBean("studentDaoImpl");
    studentDao.saveStudent();
    studentDao.queryStudent();
}
}

基于schema的AOP

//没做测试

基于@AspectJ的AOP

applicationContext.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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-2.5.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       ">

    <!-- component-scan包含annotation-config,并且开启的注解更多 -->
    <context:component-scan base-package="com" />
    <!--Spring 默认不开启@Aspect注解 所以需要手动开启  -->
    <aop:aspectj-autoproxy />
    <!--定义实现类bean -->
    <bean id="studentDaoImpl" class="com.dao.impl.StudentDaoImpl" />

</beans>

StudentDaoAspect .java

package com.proxy;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
//需要往Spring容器注入此bean,Spring才能识别并进行AOP的配置
@Component
public class StudentDaoAspect {
    @Pointcut("execution(public void com.dao.impl.StudentDaoImpl.*Student())")
    public void pointcut() {

    }

    @AfterReturning("pointcut()")
    public void afterReturning() {
        System.out.println("after");
    }

    @Before("pointcut()")
    public void before() {
        System.out.println("before");
    }

}

StudentDaoImpl .java

package com.dao.impl;

import com.dao.StudentDao;

public class StudentDaoImpl implements StudentDao{

    @Override
    public void saveStudent() {
System.out.println("正在保存");     
    }

    @Override
    public void queryStudent() {
System.out.println("正在查询");     
    }

}

ProxyTest.java

package com.proxy;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.dao.StudentDao;
import com.dao.impl.StudentDaoImpl;



public class ProxyTest{
    @Test
public void Test(){
    ApplicationContext ctx= new ClassPathXmlApplicationContext("applicationContext.xml");
    StudentDao studentDao=new StudentDaoImpl();
    studentDao=(StudentDao) ctx.getBean("studentDaoImpl");
    studentDao.saveStudent();
    studentDao.queryStudent();
}
}

打印结果

before
正在保存
after
before
正在查询
after


1)xml配置

    <!-- component-scan包含annotation-config,并且开启的注解更多 -->
    <context:component-scan base-package="com" />
    <!--Spring 默认不开启@Aspect注解 所以需要手动开启  -->
    <aop:aspectj-autoproxy />

2)切面声明

@Aspect
public class StudentDaoAspect{
...
}

3)切入点声明

切入点是连接点的集合,Spring只支持方法执行的连接点

Spring的切入点是@Pointcut+方法(必须是void类型的方法)

    @Pointcut(value="切入点表达式",argNames="参数名列表")
    public void pointcutName() {

    }

vaule:切入点表达式
argNames:指定命名切入点方法的参数列表参数名字,可以用多个“,”分隔;这些参数将传给通知方法同名的参数
pointcutName:切入点名字,可以使用该名字进行引用该切入点表达式

@Pointcut进行命名切入点声明,指定目标方法第一个参数类型必须为String类型,并且参数类型不一致也是不匹配,通过argNames=“param”指定了把该匹配的目标方法参数传递到通知同名的参数上

4)声明通知

通知类型公式注意
前置通知@Before(
value=”切入点表达式或者命名切入点”,
argNames=”参数列表参数名”
后置返回通知@AfterReturning(
value=”切入点表达式或者命名切入点”,
argNames=”参数列表参数名”
pointcut=”切入点表达式或者命名切入点”
returning=”返回值对应参数名”
pointcut的优先级比value高,会覆盖value
后置异常通知@AfterThrowing(
value=”切入点表达式或者命名切入点”,
argNames=”参数列表参数名”
pointcut=”切入点表达式或者命名切入点”
throwing=”异常对应参数名”
pointcut会覆盖value
后置最终通知@After(
value=”切入点表达式或者命名切入点”,
argNames=”参数列表参数名”
环绕通知@Around(
value=”切入点表达式或者命名切入点”,
argNames=”参数列表参数名”
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值