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的主要内容,如果未能解决你的问题,请参考以下文章

JAVA之AOP

Spring AOP

Spring源码高级笔记之——Spring AOP应用

2018.12.24 Spring中的aop演示

Spring框架 AOP

Spring的AOP面向切面编程