34、深入解析spring技术$4

AOP(Aspect Oriented Programming),面向切面编程,AOP基于IoC基础,是对OOP(Object-Oriented Programing,面向对象编程)的补充和完善。

是对所有对象或者是一类对象编程,核心是( 在增加代码的基础上,增加新功能 )

 

汇编(伪机器指令 mov jump) 面向机器

c语言(面向过程  底层开发,按语句顺序执行)->系统软件(操作系统,数据库, 杀毒软件,防火墙,驱动..)[开辟地址、指针、关闭地址] 

java(面向对象  出现了类/对象 可以调用对象方法执行)

spring(面向切面  对一批类、对象  执行操作) 


OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如fun()这个功能,这种散布在各个类中又无关(耦合)的代码称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

使用“横切”技术,AOP把系统分为两个部分:核心关注点(Core business concerns  核心业务逻辑)和横切关注点(Crosscutting enterprise concerns  通用(业务支撑)逻辑  比如权限管理、日志、事务处理)。Aop 的作用将核心关注点和横切关注点分离开来。

 

实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

 

通知(Advice) :是一个接口,可以把业务支撑功能放在这个类中,采用动态代理技术,添加到对象的业务逻辑功能中,通知5类:

前置通知Before            org.springframework.aop.MethodBeforeAdvice            在目标方法执行前  调用

后置通知After               org.springframework.aop.AfterRetruingAdvice              在目标方法执行后  调用

环绕通知Around           org.springframework.aop.MethodInterceptor                 在目标方法执行前后 调用

异常通知Throws           org.springframework.aop.ThrowsAdvice                       当目标方法抛出异常时  调用

引入通知Introduction    org.springframework.aop.IntroductionInterceptor          在目标类中添加新方法和属性

 

下面编写一个前置通知 来熟悉如何使用:

设计:


 

public interface Demo1 {
	public void say();
}

public class DemoA implements Demo1 {
	private String name ;
	public String getName() {
		return name;
	}

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

	public void say() {
		System.out.println("i'm a :"+name );
	}
}

public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
	/*
	 * 一定要实现通知接口
	 * method:目标方法
	 * args:目标方法参数
	 * target:目标对象
	 */
	public void before(Method method, Object[] args, Object target)  throws Throwable {
		System.out.println("前置通知:"+method.getName());
	}
}

  配置beans.xml 注意:全域、ref、value:
<?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:context="http://www.springframework.org/schema/context"
		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/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
				http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 配置目标对象 -->
<bean id="demoa" class="org.nickfover.test.DemoA">
<property name="name" value="skx"></property>
</bean>
<bean id="demob" class="org.nickfover.test.DemoB">
<property name="name" value="rrr"></property>
</bean>
<!-- 配置通知 -->
<bean id="myMethodBeforeAdvice" class="org.nickfover.test.MyMethodBeforeAdvice"></bean>
<!-- 配置代理 ,添加目标接口集、目标对象、织入通知-->
<bean id="proxyFactoryBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 在代理对象中配置需要代理的接口集,属性为proxyInterfaces,要写全域 -->
<property name="proxyInterfaces">
	<list>
	 	<value>org.nickfover.test.Demo1</value>
	</list>
</property>
<!--代理的目标对象,ref上面的bean  -->
<!-- property name="target" ref="demoa"/
-->
<property name="target" ref="demob"/>

<!-- 通知,注意这里的value是引用上面的bean -->
<property name="interceptorNames">
	<value>myMethodBeforeAdvice</value>
</property>
</bean>
</beans>	
 测试:
public static void main(String[] args) throws Exception {
		ApplicationContext ac = new ClassPathXmlApplicationContext("org/nickfover/test/beans.xml");
//		DemoA a =(DemoA) ac.getBean("demoa");
//		a.say();
		//一定要用接口转义
		Demo1 a =(Demo1) ac.getBean("proxyFactoryBean");
		a.say();
	}
输出:
前置通知:say
i'm b:rrr
在aop实现中,使用的核心技术是动态代理,在28章中,动态代理需要实现InvocationHandler接口,在创建代理类的时候需要引用Proxy的newProxyInstance()方法;这里的"proxyFactoryBean"与new ProxyImpl1().createProxy(new Impl1());是一样的作用; #####################################################################################################################

 ##################################################################################################################

    


 

 

猜你喜欢

转载自nickfover.iteye.com/blog/2124720