Spring aop
Posted 温一壶月光当茶饮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring aop相关的知识,希望对你有一定的参考价值。
1 AOP理解
AOP Aspect Oriented Programing 面向切面编程 --简单来说可以在原来的方法执行的逻辑增加一些新的逻辑
*AOP:面向切面编程.不是替代面向对象,对面向对象扩展,延伸.
* AOP的思想:
* 代理机制.(横向抽取).
* Spring使用AOP的时候,根据类的情况,自动选择代理机制:
* JDK :针对实现了接口的类生成代理.
* CGLIB :针对没有实现接口的类生成代理.生成某个类的子类.
2 Spring的AOP代理:
JDK动态代理:对实现了接口的类生成代理
CGLib代理机制:对类生成代理
3 代理
(1) jdk 代理
步骤:
1 编写被代理对象 ,UserDao 接口 UserDaoImpl实现类
2 编写代理对象 (实现InvocationHandler接口)
创建代理对象
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import org.springframework.stereotype.Component; @Component public class Myproxy implements InvocationHandler { private UserDao userDao=new UserDaoImpl(); public Myproxy(UserDao userDao) { super(); this.userDao = userDao; } public UserDao createProxy() { UserDao proxy = (UserDao) Proxy.newProxyInstance(userDao.getClass() .getClassLoader(), userDao.getClass().getInterfaces(), this); return proxy; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub System.out.println("增强"); return method.invoke(userDao, args); } }
测试:
@Test public void test() { Myproxy myproxy = new Myproxy(userDao); UserDao userDao = myproxy.createProxy(); userDao.delete(); }
cglib代理
步骤:
1 编写被代理对象 ,UserDao 接口 UserDaoImpl实现类
2 编写代理对象 (实现MethodInterceptor接口)
class MyCglib implements MethodInterceptor{ @Autowired OrderDao orderDao; public MyCglib(OrderDao orderDao) { super(); this.orderDao = orderDao; } public OrderDao createProxy(){ // 使用CGLIB生成代理: // 1.创建核心类:Enhancer Enhancer enhancer = new Enhancer(); // 2.为其设置父类: enhancer.setSuperclass(orderDao.getClass()); // 3.设置回调: enhancer.setCallback(this); // 4.创建代理: return (OrderDao) enhancer.create(); } @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { // TODO Auto-generated method stub if("show".equals(arg1.getName())){ System.out.println("========show======"); Object obj = arg3.invokeSuper(arg0, arg2); return obj; } return arg3.invokeSuper(arg0, arg2); }
3 Spring的AOP的开发: 传统开发方式有 生成代理()
针对所有方法的增强:(不带有切点的切面)
第一步:导入相应jar包.
* spring-aop-3.2.0.RELEASE.jar
* com.springsource.org.aopalliance-1.0.0.jar
第二步:编写被代理对象:
* CustomerDao接口
* CustoemrDaoImpl实现类
第三步:编写增强的代码:
public class MyBeforeAdvice implements MethodBeforeAdvice{
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("前置增强...");
}
}
· 第四步 配置xml
<!-- 定义目标对象 -->
<bean id="customerDao" class="cn.itcast.spring3.demo3.CustomerDaoImpl"></bean>
<!-- 定义增强 -->
<bean id="beforeAdvice" class="cn.itcast.spring3.demo3.MyBeforeAdvice"></bean>
<!-- Spring支持配置生成代理: -->
<bean id="customerDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 设置目标对象 -->
<property name="target" ref="customerDao"/>
<!-- 设置实现的接口 ,value中写接口的全路径 -->
<property name="proxyInterfaces" value="cn.itcast.spring3.demo3.CustomerDao"/>
<!-- 配置增强 需要使用value:要的名称 -->
<property name="interceptorNames" value="beforeAdvice"/>
</bean>
带有切点的切面:(针对目标对象的某些方法进行增强)
PointcutAdvisor 接口:
DefaultPointcutAdvisor 最常用的切面类型,它可以通过任意Pointcut和Advice 组合定义切面
RegexpMethodPointcutAdvisor 构造正则表达式切点切面
第一步:创建被代理对象.
* OrderDao
第二步:编写增强的类:
public class MyAroundAdvice implements MethodInterceptor{
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("环绕前增强...");
Object result = methodInvocation.proceed();// 执行目标对象的方法
System.out.println("环绕后增强...");
return result;
}
}
第三步:生成代理:
<!-- 1配置被代理对象 --> <bean id="userserv" class="demo2_aop_ogi_pointcut.UserServImpladd"></bean> <!-- 2配置增强bean --> <bean id="before" class="demo2_aop_ogi_pointcut.MyBeforeAdvise"></bean> <!-- 亚配置切面 --> <bean id="myPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <!-- 配置切点 patterns 可以配置多个切点 默认使用逗号隔开 --> <property name="pattern" value="demo2_aop_ogi_pointcut.IUserServ.*dd.*"></property> <!-- 配置增强 --> <property name="advice" ref="before"></property> </bean> <bean id="userservProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <!-- 配置接口 --> <property name="proxyInterfaces" value="demo2_aop_ogi_pointcut.IUserServ"></property> <!-- 配置目标对象 --> <property name="target" ref="userserv" /> <!-- 配置增强 --> <property name="interceptorNames" value="myPointcutAdvisor"></property> </bean>
《2》自动代理
1 编写接口和实现类
2 编写增强的类
3 配置代理
增强的类
public class MyBeforeAdvise implements MethodBeforeAdvice { /** * @param method:执行的方法 * @param args:参数 * @param target:目标对象 */ @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("auto----------before"); //method.invoke(target, args); } public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable { System.out.println("after"); } public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("环绕前增强..."); methodInvocation.proceed();// 执行目标对象的方法 System.out.println("环绕后增强..."); return null; } }
配置xml
<bean id="userdao" class="demo3_aop_autoproxy.UserDao"></bean>
<bean id="orderd" class="demo3_aop_autoproxy.OrderDao"></bean> <bean id="before" class="demo3_aop_autoproxy.MyBeforeAdvise"></bean> <!-- 亚配置切面 --> <bean id="myPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="pattern" value=".*add.*" /> <property name="advice" ref="before" /> </bean>
/* 如果不考虑切点*/ <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <property name="beanNames" value="*dao" /> <property name="interceptorNames" value="before" />
</bean>
/* 如果不考虑切点*/
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
</bean>
以上是关于Spring aop的主要内容,如果未能解决你的问题,请参考以下文章