java 高新技术【11.2】 动态代理类 编写类似 AOP 与 BeanFactory。初试Spring框架

1.切面(aspect):    要实现的交叉功能,是系统模块化的一个切面或领域。如日志记录。
2.连接点:    应用程序执行过程中插入切面的地点,可以是方法调用,异常抛出,或者要修改的
字段。
3.通知:    切面的实际实现,他通知系统新的行为。如在日志通知包含了实
现日志功能的代码,如向日志文件写日志。通知在连接点插入到应用系统中。
4.切入点:    定义了通知应该应用在哪些连接点,通知可以应用到AOP框架支持的任何连接点。
5.引入:    为类添加新方法和属性。
6.目标对象:    被通知的对象。既可以是你编写的类也可以是第三方类。
7.代理:    将通知应用到目标对象后创建的对象,应用系统的其他部分不用为了支持代理对象而
改变。
8.织入:    将切面应用到目标对象从而创建一个新代理对象的过程。织入发生在目标
对象生命周期的多个点上:
编译期:  切面在目标对象编译时织入.这需要一个特殊的编译器.
类装载期:  切面在目标对象被载入JVM时织入.这需要一个特殊的类载入器.
运行期:  切面在应用系统运行时织入.

AOP的几个重点概念:

1、Spring只支持方法拦截,也就是说,只能在方法的前后进行拦截,而不能在属性前后进行拦截。
2、Spring支持四种拦截类型:目标方法调用前(before),目标方法调用后(after),目标方法调用前后(around),以及目标方法抛出异常(throw)。
3、前置拦截的类必须实现MethodBeforeAdvice接口,实现其中的before方法。
4、后置拦截的类必须实现AfterReturningAdvice接口,实现其中的afterReturning方法。
5、前后拦截的类必须实现MethodInterceptor接口,实现其中的invoke方法。前后拦截是唯一可以控制目标方法是否被真正调用的拦截类型,也可以控制返回对象。而前置拦截或后置拦截不能控制,它们不能印象目标方法的调用和返回。

但是以上的拦截的问题在于,不能对于特定方法进行拦截,而只能对某个类的全部方法作拦截。


所以下面引入了两个新概念:“切入点”和“引入通知”。

6、”切入点“的定义相当于更加细化地规定了哪些方法被哪些拦截器所拦截,而并非所有的方法都被所有的拦截器所拦截。在ProxyFactoryBean的属性中,interceptorNames属性的对象也由拦截(Advice)变成了引入通知(Advisor),正是在Advisor中详细定义了切入点(PointCut)和拦截(Advice)的对应关系,比如常见的基于名字的切入点匹配(NameMatchMethodPointcutAdvisor类)和基于正则表达式的切入点匹配(RegExpPointcutAdvisor类)。这些切入点都属于”静态切入点“,因为他们只在代理创建的时候被创建一次,而不是每次运行都创建。


import java.lang.reflect.Method;

public interface Advice {
	void beforeMethod(Method method);
	void afterMethod(Method method);
}

import java.lang.reflect.Method;

public class MyAdvice implements Advice {
	long beginTime = 0;
	public void afterMethod(Method method) {
		System.out.println("操作方法后");		
		long endTime = System.currentTimeMillis();
		System.out.println(method.getName() + " running time of " + (endTime - beginTime));

	}

	public void beforeMethod(Method method) {
		System.out.println("操作方法前");
		beginTime = System.currentTimeMillis();
	}

}

package com.itm.day3.aopframework;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyFactoryBean {

	private Advice advice;
	private Object target;
	
	public Advice getAdvice() {
		return advice;
	}

	public void setAdvice(Advice advice) {
		this.advice = advice;
	}

	public Object getTarget() {
		return target;
	}

	public void setTarget(Object target) {
		this.target = target;
	}

	public Object getProxy() {
		Object proxy3 = Proxy.newProxyInstance(
				target.getClass().getClassLoader(),
				target.getClass().getInterfaces(),
				new InvocationHandler(){
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						advice.beforeMethod(method);
						
						// 调用方法。。。
						Object retVal = method.invoke(target, args);
						
						advice.afterMethod(method);
						return retVal;						
					}
				}
				);
		return proxy3;
	}

}

package com.itm.day3.aopframework;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;


public class BeanFactory {
	Properties props = new Properties();
	
	public BeanFactory(InputStream ips){
		try {
			props.load(ips);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public Object getBean(String name){
		// 拿到  类名。
		String className = props.getProperty(name);
		
		Object bean = null;
		
		try {
			Class clazz = Class.forName(className);
			// 创建一个对象:【不带参数的构造方法】
			bean = clazz.newInstance();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if(bean instanceof ProxyFactoryBean){
			
			Object proxy = null;
			
			 // 这时就可以  创建  那个代理对象的。。。
			try {
				ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean)bean;
				
				Advice advice =(Advice) Class.forName(props.getProperty(name + ".advice")).newInstance();
				Object target = Class.forName(props.getProperty(name + ".target")).newInstance();
				
				proxyFactoryBean.setAdvice(advice);
				proxyFactoryBean.setTarget(target);
				
				proxy = proxyFactoryBean.getProxy();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			return proxy;
		}
		return bean;
	}
	
}

public class AopFrameworkTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");
		Object bean = new BeanFactory(ips).getBean("xxx");
		
		System.out.println("這是什麽:"+bean.getClass().getName());
		
		((Collection)bean).clear();
		System.out.println("-----");
	}

}



说明:

#xxx=java.util.ArrayList   注释这一段代码 就会去找 代理类。

#xxx=com.itm.day3.aopframework.ProxyFactoryBean  注释这一段代码,就不用找代理类了 就去真正的类。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值