转载

Spring AOP

连接点

指那些被拦截到的点。。

拦截到的方法

切入点

要对那些连接点进行拦截定义。。

通知,增强

拦截之前通知,之后通知

引介

在不修改类的情况下,动态的添加。。

目标对象

代理的目标对象

织入

把增强应用到目标对象,创建新的代理对象的过程称为织入,

代理

一个类被AOP代理以后,会产生结果代理类

前置通知

package com.ming.demo7;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

/**
 * 前置通知
 * @author ming
 */
public class MyBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("前置通知=============");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<bean id="studentDao" class="com.ming.demo7.StudentDaoImpl"/>
	
	<!-- 前置通知 -->
	<bean id="myBeforeAdvice" class="com.ming.demo7.MyBeforeAdvice"/>
</beans>

代理对象

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<bean id="studentDao" class="com.ming.demo7.StudentDaoImpl"/>
	
	<!-- 前置通知类型 -->
	<bean id="myBeforeAdvice" class="com.ming.demo7.MyBeforeAdvice"/>

	<!-- 产生代理对象 -->
	<bean id="studentDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<!-- 目标类 -->
		<property name="target" ref="studentDao"/>
		<!-- 实现的接口 -->
		<property name="proxyInterfaces" value="com.ming.demo7.StudentDao"/>
		<!--采用拦截的名称  -->
		<property name="interceptorNames" value="myBeforeAdvice"/>
  	</bean>
</beans>
package com.ming.demo7;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class StudentDaoImplTest {
    @Autowired
    private StudentDao studentDaoProxy;

    @Test
    public void find() {
        studentDaoProxy.find();
    }

    @Test
    public void update() {
        studentDaoProxy.update();
    }

    @Test
    public void delete() {
        studentDaoProxy.delete();
    }
}
package com.ming.demo7;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

/**
 * 前置通知
 * @author ming
 */
public class MyBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println(method.getName());
        System.out.println("前置通知=============");
    }
}
package com.ming.demo7;

public interface StudentDao {
    public void find();

    public void update();

    public void delete();
}
package com.ming.demo7;

public class StudentDaoImpl implements StudentDao {
    @Override
    public void find() {
        System.out.println("查找");
    }

    @Override
    public void update() {
        System.out.println("更新");
    }

    @Override
    public void delete() {
        System.out.println("删除");
    }
}

这里使用的是jdk的动态代理

使用cglib动态代理使用

optimize 为 true

切点 切面

如果需要拦截一个方法 或者某几个方法 使用带有切入点的切面

这是环绕通知

package com.ming.demo8;

public class CustomerDao {
    public void find(){
        System.out.println("查询客户");
    }

    public void save(){
        System.out.println("保存客户");
    }

    public void update(){
        System.out.println("更新客户");
    }

    public void delete(){
        System.out.println("删除");
    }
}
package com.ming.demo8;


import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyAroundadvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("执行前操作");

        // 执行方法的操作
        Object obj = methodInvocation.proceed();

        System.out.println("执行后操作");

        return obj;
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- 目标类 -->
	<bean id="customerDao" class="com.ming.demo8.CustomerDao"/>
	
	<!-- 环绕通知 -->
	<bean id="myAroundAdvice" class="com.ming.demo8.MyAroundadvice"/>
	
	<!-- 对目标某些方法增强需要配置 使用正则配置 -->
	<bean id="myAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<!-- 正则匹配 .任意字符  * 任意次数-->
		<property name="pattern" value=".*"/>
		<!-- 环绕通知 -->
		<property name="advice" ref="myAroundAdvice"/>
	</bean>
	
	<!-- 产生代理 -->
	<bean id="customerDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="customerDao"/>
		<property name="proxyTargetClass" value="true"/>
		<property name="interceptorNames" value="myAdvisor"/>
	</bean>
</beans>
package com.ming.demo8;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class CustomerDaoTest {
    @Autowired
    CustomerDao customerDaoProxy;


    @Test
    public void find() {
        customerDaoProxy.find();
    }

    @Test
    public void save() {
        customerDaoProxy.save();
    }

    @Test
    public void update() {
        customerDaoProxy.update();
    }

    @Test
    public void delete() {
        customerDaoProxy.delete();
    }
}

基于bean名称自动代理

对以DAO结尾的Bean进行结尾

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- 配置目标类 -->
	<bean id="studentDao" class="com.ming.demo10.StudentDaoImpl"/>
	<bean id="customerDao" class="com.ming.demo10.CustomerDao"/>
	
	<!-- 配置增强 -->
	<!-- 前置增强 -->
	<bean id="myBeforeAdvice" class="com.ming.demo10.MyBeforeAdvice"/>
	<!-- 后置增强 -->
	<bean id="myAroundAdvice" class="com.ming.demo10.MyAroundadvice"/>
	
	<!-- 自动代理 -->
	<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<!-- 配置那种目标类 -->
		<property name="beanNames" value="*Dao"/>
		<!-- 使用那种增强 -->
		<property name="interceptorNames" value="myBeforeAdvice"/>
 	</bean>
</beans>
package com.ming.demo10;

public class CustomerDao {
    public void find(){
        System.out.println("查询客户");
    }

    public void save(){
        System.out.println("保存客户");
    }

    public void update(){
        System.out.println("更新客户");
    }

    public void delete(){
        System.out.println("删除");
    }
}
package com.ming.demo10;


import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyAroundadvice implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("执行前操作");

        // 执行方法的操作
        Object obj = methodInvocation.proceed();

        System.out.println("执行后操作");

        return obj;
    }
}
package com.ming.demo10;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class MyBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("前置增强=========");
    }
}
package com.ming.demo10;

public interface StudentDao {
    public void find();

    public void update();

    public void delete();
}
package com.ming.demo10;

public class StudentDaoImpl implements StudentDao {
    @Override
    public void find() {
        System.out.println("查找");
    }

    @Override
    public void update() {
        System.out.println("更新");
    }

    @Override
    public void delete() {
        System.out.println("删除");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<!-- 配置目标类 -->
	<bean id="studentDao" class="com.ming.demo10.StudentDaoImpl"/>
	<bean id="customerDao" class="com.ming.demo10.CustomerDao"/>
	
	<!-- 配置增强 -->
	<!-- 前置增强 -->
	<bean id="myBeforeAdvice" class="com.ming.demo10.MyBeforeAdvice"/>
	<!-- 后置增强 -->
	<bean id="myAroundAdvice" class="com.ming.demo10.MyAroundadvice"/>
	
	<!-- 自动代理 -->
	<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<!-- 配置那种目标类 -->
		<property name="beanNames" value="*Dao"/>
		<!-- 使用那种增强 -->
		<property name="interceptorNames" value="myBeforeAdvice"/>
 	</bean>
</beans>
package com.ming.demo10;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import static org.junit.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class StudentDaoImplTest {
    @Autowired
    private StudentDao studentDao;
    @Autowired
    private CustomerDao customerDao;

    @Test
    public void find() {
        studentDao.find();
        customerDao.find();
    }

    @Test
    public void update() {
        studentDao.update();
        customerDao.update();
    }

    @Test
    public void delete() {
        studentDao.delete();
        customerDao.delete();
    }
}

对某些类的某些方法代理

对切面进代理

好吧,,这个解决不了

总结

连接点: 那些被拦截到的方法

切入点 要对那些连接点进行定义为切入点

通知: 在切入点执行之前进行通知,之后进行通知。

引介: 在不修改类的代码的前提下

目标对象: 动态生成的对象

织入 创建新的代理的过程

代理: 动态产生代理的过程

切面 切入点和连接点的结合

原文  https://www.iming.info/spring-aop/
正文到此结束
Loading...