Spring-Aop

Aop( aspect oriented programming ) 面向切面(方面)编程,是对所有对象或者是一类对象编程,核心是不增加代码的基础上, 还增加新功能 )


步骤:

1. 定义接口

2. 编写对象(被代理对象=目标对象)

3. 编写通知(前置通知目标方法调用前调用)

4. 在beans.xml文件配置

4.1 配置 被代理对象=目标对象

4.2 配置通知

4.3 配置代理对象 是 ProxyFactoryBean的对象实例

4.3.1 <!-- 代理接口集 -->

4.3.2 织入通知

4.3.3 配置被代理对象


切面:交叉功能

织入:把交叉功能织入到Proxy对象

连接点->切入点


通知:

前置通知,后置通知,环绕通知,异常通知,引入通知


实例如下:

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:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
	<!-- 配置被代理对象,配置前置通知对象,配置代理对象 -->
	<bean id="Test1Service" class="com.hsp.aop.Test1Service">
		<property name="name" value="lv" />
	</bean>
	
	
		
	
	
	
	<bean id="MyMethodBeforeAdvice" class="com.hsp.aop.MyMethodBeforeAdvice">
	</bean>
	<!-- 配置后置通知 -->
	<bean id="MyMethodAfterAdvice" class="com.hsp.aop.MyMethodAfterAdvice">
	</bean>
	<!-- 配置环绕通知 -->
	<bean id="HuanRaoTongZhi" class="com.hsp.aop.HuanRaoTongZhi">
	</bean>
	<bean id="MyThrowsAdvice" class="com.hsp.aop.MyThrowsAdvice"></bean>
	<!-- 引入通知 定义切入点 -->
	<bean id="LeadIntoMyAdvice" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
		<property name="advice" ref="MyMethodBeforeAdvice"></property>
		<property name="mappedNames">
		<list>
		<value>sayBye</value>
		</list>
		</property>
	</bean>
	<bean id="ProxyFactoryBean1" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="proxyInterfaces">
			<!-- 代理接口集 -->
			<list>
				<value>com.hsp.aop.TestServiceInterface</value>
				<value>com.hsp.aop.TestServiceInterface2</value>
			</list>
		</property>
		<!-- 把通知织入到代理对象 -->
		<property name="interceptorNames">
			<list>
				<!-- 前置对象和代理对象关联起来 ,可以把通知看成拦截器 -->


				<!-- <value>MyMethodBeforeAdvice</value> -->
				<!-- 后置通知和代理对象关联起来,可以把 -->
				<value>MyMethodAfterAdvice</value>
				<value>HuanRaoTongZhi</value>
				<value>MyThrowsAdvice</value>
				<!-- 使用自定义切入点控制 前置通知 -->
				<value>LeadIntoMyAdvice</value><!-- 前置通知指定sayHello 把前置去掉,生成前置 -->
				


			</list>
		</property>
		
		
		<!--配置 被代理对象 -->
		<property name="target" ref="Test1Service" />
	</bean>
</beans>
接口

public interface TestServiceInterface {
   void sayHello();
}
接口2

public interface TestServiceInterface2 {
   void sayBye();
}

继承类

public class Test1Service implements TestServiceInterface,TestServiceInterface2{

	private String name;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public void sayHello() {
		// TODO Auto-generated method stub
		System.out.println("hello my lover  sayHello()"+name);
		//System.out.println(8/0);
		
	}
	public void sayBye() {
		System.out.println("I am the interface2 sayBye()"+name);
		
	}
	

}

前置通知

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
 
	/*
	 * method被调用的方法名
	 * args给方法传递的参数有哪些
	 * target 调用该方法的目标对象
	 * 代理对象只需配置不需要写,使用到动态代理技术
	 * @see org.springframework.aop.MethodBeforeAdvice#before(java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
	 */
	@Override
	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		// TODO Auto-generated method stub
		System.out.println(" 前置通知    目前没有记录日志    哪个方法被调用"+method.getName());
		
	}	
}

后置通知

import java.lang.reflect.Method;

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

public class MyMethodAfterAdvice implements AfterReturningAdvice {

	@Override
	public void afterReturning(Object returnValue, Method method,
			Object[] args, Object target) throws Throwable {
		System.out.println("后置通知资源已经关闭"+method.getName());
		
	}
 
	/*
	 * method被调用的方法名
	 * args给方法传递的参数有哪些
	 * target 调用该方法的目标对象
	 * 代理对象只需配置不需要写,使用到动态代理技术
	 * @see org.springframework.aop.MethodBeforeAdvice#before(java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
	 */
	
}

环绕通知

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

public class HuanRaoTongZhi implements MethodInterceptor{

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println(" 调用前"+arg0.getMethod());
		Object o=arg0.proceed();
		System.out.println("调用后");
		return o;
	}

}

异常通知

import java.lang.reflect.Method;

import org.springframework.aop.ThrowsAdvice;

public class MyThrowsAdvice implements ThrowsAdvice {
	
	/*public void afterThrowing(Throwable throwable)
	{
		
	}*/
	public void afterThrowing(Method m, Object args, Object target,  
            Throwable subclass) {  
        System.out.println("[DaoThrowsAdvice]: An exception occur: "  
                + subclass.getClass().getSimpleName()+":"+subclass.getMessage());  
        System.exit(0);  
    }  
	

}
测试类

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

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ApplicationContext ac=new ClassPathXmlApplicationContext("com/hsp/aop/beans.xml");
		/*Test1Service te=(Test1Service) ac.getBean("Test1Service");
		te.sayHello();*/
		TestServiceInterface pfb=(TestServiceInterface) ac.getBean("ProxyFactoryBean1");
		//TestServiceInterface2 pfb1=(TestServiceInterface2) ac.getBean("ProxyFactoryBean1");
		/*
		 * pfb:Spring Aop中当你通过代理对象去实现Aop技术的时候,获取的proxyFactorybean是什么类型
		 * 返回的是一个代理对象,如果目标对象实现了接口,则Spring使用jdk的动态代理技术完成
		 * 如果目标对象没有实现接口,则Spring使用CGlib的动态代理技术完成
		 */
		//切入点可以用正则表达式匹配
		System.out.println("pfb类型是"+pfb);
		pfb.sayHello();
		
		((TestServiceInterface2)ac.getBean("ProxyFactoryBean1")).sayBye();
		//pfb1.sayBye();
		//引入通知自定义切入点
	}

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值