spring-Aop 1.2(1) aop(前置通知)体验

        加入通知的地点可以为:方法调用,异常抛出,要修改的字段。spring采用方法调用,有四种加入通知的方式:前置通知,后置通知,环绕通知,异常通知,通知也有两种代理方式,①jdk的动态代理,即接口代理②对类代理,即cglib代理。推荐①,耦合性低,且使用②的话,要考虑final修饰的方法不能被代理,因为不能被重写,无法织入通知。

具体专有名词不够清楚,可以看:

https://blog.csdn.net/haidaoxianzi/article/details/79778324

对目标对象,通知,代理的关系,可以理解为如下图示:


以下为体验aop,通过接口代理的前置通知demo。

1 定义接口,目标对象,以及前置通知

①前置通知

package cn.dbe.spring.aop.advice;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

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

②接口1,2

package cn.dbe.spring.aop.service;
public interface WelcomeService {
    void sayName(String a);
}
package cn.dbe.spring.aop.service;

public interface WelcomeService2 {
    void sayName2(String b);
}

③目标对象

package cn.dbet.spring.aop.service.impl;
import cn.dbe.spring.aop.service.WelcomeService;
import cn.dbe.spring.aop.service.WelcomeService2;

public class WelcomeServiceImpl implements WelcomeService, WelcomeService2 {
    private String name;
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void sayName(String a) {
        System.out.println(a + "+" + name);
    }

    @Override
    public void sayName2(String b) {
        System.out.println(b + "+" + name);
    }
}

2 在配置文件中通过代理工厂bean定义代理对象,属性来配置通过哪个“接口”来代理,从而对“目标对象” 织入 “通知”。

<?xml version="1.0"?>
<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-3.0.xsd">
           <!-- 目标对象 -->
        <bean id="welcomeServiceTarget" class="cn.dbet.spring.aop.service.impl.WelcomeServiceImpl">
           <property name="name" value="123wq"/>
        </bean>
        
        <!-- 前置通知 -->
        <bean id="myMethodBeforeAdvice" class="cn.dbe.spring.aop.advice.MyMethodBeforeAdvice"/>

        <!-- 代理 -->
	<bean id="welcomeService" class="org.springframework.aop.framework.ProxyFactoryBean">		  
              <!-- 拦截器名集 -->
	      <property name="interceptorNames">
	          <list>
		      <value>myMethodBeforeAdvice</value>
		  </list>
	       </property>
			  
		<!-- 代理接口集合 ,接口代理-->
		<property name="proxyInterfaces">
		   <list>
			<value>cn.dbe.spring.aop.service.WelcomeService</value>
			<value>cn.dbe.spring.aop.service.WelcomeService2</value>
		   </list>
		</property>
			  
		<!-- 目标对象 -->
		<property name="target" ref="welcomeServiceTarget"/>
			  
		<!-- 代理目标类,对类代理(cglib代理),需要引入第三方依赖类库 -->
		<property name="proxyTargetClass" value="true"/>
	</bean>        
</beans>

3 test

package cn.dbet.spring.aop;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.dbe.spring.aop.service.WelcomeService;

public class App {
   public void testService() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("aop.xml", App.class);

        //接口代理
        System.out.println("--接口代理start");
        WelcomeService w = (WelcomeService) ac.getBean("welcomeService");
        w.sayName("a");
        WelcomeService2 w2 = (WelcomeService2) w;//(WelcomeService2) ac.getBean("welcomeService");
        w2.sayName2("b");

        WelcomeServiceImpl w3 = (WelcomeServiceImpl) ac.getBean("welcomeServiceTarget");
        System.out.println("--普通的调用类的方法,不会加入通知 start--");
        w3.sayName("c");
        w3.sayName2("c");

        //对类代理 ,cglib代理,原理:通过继承代理对象实现对类代理
        WelcomeServiceImpl w4 = (WelcomeServiceImpl) w;
        System.out.println("--对类代理");
        w4.sayName("d");
        w4.sayName2("d");
    }
}
输出结果为:
--接口代理start
into MyMethodBeforeAdvice
a+123wq
into MyMethodBeforeAdvice
b+123wq
--普通的调用类的方法,不会加入通知 start--
c+123wq
c+123wq
--对类代理
into MyMethodBeforeAdvice
d+123wq
into MyMethodBeforeAdvice
d+123wq
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值