动态代理实现Spring Aop

引言

我们在前两篇文章中,都为这篇做了铺垫,我们现在来做这样一件事情,在业务逻辑中添加Aop的非业务逻辑。

AopClinetTest:

package com.tgb.client;

import com.tgb.config.BeanFactory;
import com.tgb.config.ClassPathXmlApplicationContext;
import com.tgb.dao.UserDao;
import com.tgb.domain.User;
/**
 * AOP效果测试
* @ClassName: AopClientTest
* @Description: TODO(这里用一句话描述这个类的作用)
* @author [qmx]
* @date
*
 */
public class AopClientTest {

	public static void main(String[] args) throws Exception {
		//初始化容器对象
		BeanFactory factory = new ClassPathXmlApplicationContext();

		User user = new User();
		user.setUserName("hanyankun");
		//获取容器中userDao对象
		UserDao userDao = (UserDao)factory.getBean("UserDao");

		userDao.update(user);

	}
}

AspectCacheBean:

package com.tgb.config;

import com.tgb.util.MethodCatch;
/**
* @ClassName: AspectCachBean
* @Description:
* 缓存服务类,实现了对缓存的,前置,后置, 保存的方法
* @author [qmx]
* @date
*
 */
public class AspectCachBean {

	@MethodCatch(methodName="cacheBefore")
	public  void cacheBefore(Object proxy) {

		System.out.println("---这是切入 类AspectCachBean  cacheBefore()-方法--");
	}

	@MethodCatch(methodName="cacheAfter")
	public static void cacheAfter(Object proxy) {
		System.out.println("---这是切入 类AspectCachBean  cacheAfter()-方法--");
	}
	@MethodCatch(methodName="cacheSave")
	public void cacheSave(Object proxy){
		System.out.println("---这是切入 类AspectCachBean  cacheSave()-方法--");
	}
}

AspectCertifiyBean:

package com.tgb.config;

import com.tgb.util.MethodCatch;
/**
 *
* @ClassName: AspectCertifiyBean
* @Description: 认证服务类,提供了认证前, 认证后,认证保存的方法
* @author [qmx]
* @date
*
 */
public class AspectCertifiyBean {

	@MethodCatch(methodName = "certifiyBefore")
	public void certifiyBefore(Object proxy) {

		System.out.println("---这是切入 类AspectCertifiyBean  certifiyBefore()-方法--");
	}

	@MethodCatch(methodName = "certifyAfter")
	public  void certifyAfter(Object proxy) {
		System.out.println("---这是切入 类AspectCertifiyBean  certifyAfter()-方法--");
	}

	@MethodCatch(methodName = "certifySave")
	public void certifySave(Object proxy) {
		System.out.println("---这是切入 类AspectCertifiyBean  certifySave()-方法--");
	}
}

BeanFactory:

package com.tgb.config;

import java.util.List;
import java.util.Map;
/**
 *
* @ClassName: ContainerBeans
* @Description: 容器接口,提供容器公共服务方法, 增加,删除,遍历,获取对象,遍历类型,容器大小等方法
* @author [qmx]
* @date
*
 */
public interface BeanFactory {
	/**
	 * 获取容器中指定对象
	 *
	 * @param id
	 *            对象名称如: getBean("user")
	 * @return
	 */
	public Object getBean(String id);

	/**
	 * 容器中放入对象
	 *
	 * @param k
	 * @param v
	 * @return
	 */
	public Object put(String k, Object v);

	/**
	 * 打印容器中所有对象类型
	 */
	public void printTypeName();

	/**
	 * 获取容器中所有对象 返回类型 Map<string(对象类型),Object(对象)>
	 *
	 * @return Map<string(对象类型),Object(对象)>
	 */
	public Map<String, Object> getAllBean();

	/**
	 * 获取容器所有bean
	 */
	public void printAllbeanId();

	public void remove(String id);

	/**
	 * 容器中对象的数量
	 * @return
	 */
	public int size();
}

ClassPathXmlApplicationContext:

package com.tgb.config;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;

import net.sf.cglib.asm.ClassVisitor;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;

/***
 *
 *
 * @author  容器组装类, 装载 业务容器 和 切入容器。 分别将其中的 颗粒装载到各自的 beans 中
 */
public class ClassPathXmlApplicationContext implements BeanFactory {

	// 业务容器beans
	private Map<String, Object> containerBeans = new HashMap<String, Object>();

	// 切面容器beans
	private Map<String, Object> aspectBeans = new HashMap<String, Object>();

	// 设置是否需要aop
	private boolean isAop = true;

	/*
	 * 构造函数加载个容器内对象
	 */
	public ClassPathXmlApplicationContext() throws Exception {
		SAXBuilder sb = new SAXBuilder();

		// 扫描业务容器对象
		Document containerDoc = sb.build(Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("beans.xml"));

		// 扫描切入容器对象
		Document aspectDoc = sb.build(Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("aspecbeans.xml"));

		// 设置切面容器
		getAspectBeans(aspectDoc);

		// 设置业务容器bean
		getContainerBeans(containerDoc);
	}

	/***
	 * 设置业务容器装配
	 * @param doc
	 * @throws ClassNotFoundException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 */
	private void getContainerBeans(Document doc) throws InstantiationException,
			IllegalAccessException, ClassNotFoundException, NoSuchMethodException,
			SecurityException, IllegalArgumentException, InvocationTargetException {

		//读取文档根目录
		Element root = doc.getRootElement();
		//获取aop节点信息
		Element aopElement = (Element) root.getChildren("aop").get(0);
		//aop节点属性
		isAop = Boolean.parseBoolean(aopElement.getAttributeValue("isaop"));
		//获取bean节点
		List list = root.getChildren("bean");
		// 前置增强节点
		List aopBeforeList = root.getChildren("aspectbefore");
		//后置节点
		List aopAfterList = root.getChildren("aspectafter");
		//辨别增强节点是否有配置,放入bean关系容器中
		if (aopBeforeList != null) {
			containerBeans.put("aspectbefore", aopBeforeList);

		}
		if (aopAfterList != null) {
			containerBeans.put("aspectafter", aopAfterList);
		}
		//调用装备对象方法,装配业务对象
		putAllBeans(list, containerBeans);

	}

	/**
	 * 设置切入容器装配对象
	 *
	 * @param doc
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws ClassNotFoundException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 * @throws SecurityException
	 * @throws NoSuchMethodException
	 */
	private void getAspectBeans(Document doc) throws InstantiationException,
			IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {

		//读取文档根目录
		Element root = doc.getRootElement();
		List aspectElements = root.getChildren("aspectbean");//读取切入配置文件
		putAllBeans(aspectElements,aspectBeans);

	}

	/**
	 * 对象装配方法
	 * @param list 读取的配置文件
	 * @param allBeans 设置装配的容器对象
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws ClassNotFoundException
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public void putAllBeans(List list, Map<String, Object> allBeans)
			throws InstantiationException, IllegalAccessException,
			ClassNotFoundException, NoSuchMethodException, SecurityException,
			IllegalArgumentException, InvocationTargetException {

		for (int i = 0; i < list.size(); i++) {
			//获取传入父亲节点中的每个子节点,为行element
			Element element = (Element) list.get(i);
			//获取子节点中的id属性
			String id = element.getAttributeValue("id");
			//获取子节点中的class属性
			String clazz = element.getAttributeValue("class");
			//实例化class
			Object o = Class.forName(clazz).newInstance();

			//将实例化的class放入容器
			allBeans.put(id, o);

			//for循环获取 bean中的 属性property
			for (Element propertyElement : (List<Element>) element
					.getChildren("property")) {
				//获取property属性中的name属性
				String name = propertyElement.getAttributeValue("name"); // userDAO

				//获取property属性中的ref属性
				String bean = propertyElement.getAttributeValue("ref"); // 

				//获取子属性的试题
				Object beanObject = allBeans.get(bean);// UserDAOImpl

				//调用 依赖实体中的set方法(为子实体的方法)
				String methodName = "set" + name.substring(0, 1).toUpperCase()
						+ name.substring(1);

				Method m = o.getClass().getMethod(methodName,
						beanObject.getClass().getInterfaces()[0]);
				m.invoke(o, beanObject);
			}

		}
	}

	/**
	 * 获取容器中指定对象
	 *
	 * @param id
	 *            对象名称如: getBean("user")
	 * @return
	 */
	public Object getBean(String id) {

		if (!isAop) {
			return containerBeans.get(id);
		}
		return new JDKDynamicProxy(containerBeans.get(id), aspectBeans, containerBeans)
				.getProxy();
	}

	/**
	 * 容器中放入对象
	 *
	 * @param k
	 * @param v
	 * @return
	 */
	public Object put(String k, Object v) {

		return containerBeans.put(k, v);
	}

	/**
	 * 打印容器中所有对象类型
	 */
	public void printTypeName() {

		Set<String> hashSet = new HashSet<String>();
		Set<Entry<String, Object>> entryset = containerBeans.entrySet();
		{
			Iterator iterator = entryset.iterator();
			while (iterator.hasNext()) {
				Entry<String, Object> entry = (Entry<String, Object>) iterator.next();
				hashSet.add(entry.getValue().getClass().getSimpleName());
			}

		}
		for (String setType : hashSet) {
			System.out.println(setType);
		}

	}

	/**
	 * 获取容器中所有对象
	 *
	 * @return Map<string(对象类型),Object(对象)>
	 */
	public Map<String, Object> getAllBean() {
		Map<String, Object> beanList = new HashMap<String, Object>();
		Iterator iterator = containerBeans.entrySet().iterator();
		while (iterator.hasNext()) {
			Entry<String, Object> entry = (Entry<String, Object>) iterator.next();
			beanList.put(entry.getValue().getClass().getSimpleName(), entry.getValue());
		}
		return beanList;

	}

	/***
	 * 删除指定对象
	 */
	public void remove(String id) {
		containerBeans.remove(id);

	}

	/***
	 * 打印所有注入对象
	 */
	public void printAllbeanId() {
		Set<Entry<String, Object>> entryset = containerBeans.entrySet();

		Set<String> linkSet = new TreeSet<String>();
		{
			Iterator iterator = entryset.iterator();
			while (iterator.hasNext()) {
				Entry<String, Object> entry = (Entry<String, Object>) iterator.next();
				linkSet.add(entry.getKey());
				// System.out.println(entry.getKey());
			}

			System.out.println(linkSet.toString());
			System.out.println("容器中的对象个数是" + size() + "个");
		}

	}

	/**
	 * 获取容器中对象的个数
	 */
	public int size() {
		return containerBeans.size();
	}
}

JDKDynamicProxy:

package com.tgb.config;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.jdom.Element;

import com.tgb.util.MethodCatch;

/* @ClassName: JDKDynamicProxy
* @Description: AOP实现对业务容器 的增强,对业务容器中每个对象增强 服务类中的方法,根据 关系容器配置,
* 实现特性方法增强
* @author [qmx]
*/
public class JDKDynamicProxy implements InvocationHandler {

	private Object target;

	private Map<String, Object> aspectBeans; // 切入容器
	private Map<String, Object> containerBeans;// 业务容器

	/**
	 * 代理类获取代理对象,业务容器,切面容器
	 *
	 * @param target
	 *            被代理对象
	 * @param aspectBeans
	 *            切面容器
	 * @param containerBeans
	 *            业务容器
	 */
	public JDKDynamicProxy(Object target, Map<String, Object> aspectBeans,
			Map<String, Object> containerBeans) {
		this.target = target;
		this.aspectBeans = aspectBeans;
		this.containerBeans = containerBeans;
	}

	@SuppressWarnings("unchecked")
	public <T> T getProxy() {
		return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target
				.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

		List beforeList = (List) containerBeans.get("aspectbefore");//获取关系容器中的配置
		invokeAspectName(beforeList, method, args);// 调用切面类中匹配方法
		Object result = method.invoke(target, args);// 调用 被代理类本身方法

		return result;
	}

	/**
	 * 拦截方法匹配
	 *
	 * @param beforeList
	 *            拦截器的所有对象
	 * @param method
	 * @param args
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public void invokeAspectName(List beforeList, Method method, Object[] args)
			throws NoSuchMethodException, SecurityException, IllegalAccessException,
			IllegalArgumentException, InvocationTargetException {

		//if判断获取的集合是否为空,若为空则执行所有服务对象的所有方法
		if (beforeList != null && beforeList.size() != 0) {

			//for循环遍历 集合对象中的对象,获取每个对象,执行该对象中的方法
			for (int i = 0; i < beforeList.size(); i++) {

				Element element = (Element) beforeList.get(i); //获取每个对象
				String aspectClass = element.getAttributeValue("aspectId");// 获取容器中切入类名称
				String aspectName = element.getAttributeValue("aspectMethod");// 执行的切入方法
				//若对象为空,则说明
				if (aspectBeans.get(aspectClass) == null) {
					System.out.println("未找到该切入类,请查看配置的切入类名称是否正确");
					return;
				}
				Class clazz = aspectBeans.get(aspectClass).getClass(); // 获取切入类
				String elementMethod = element.getAttributeValue("method");// 获取被切入类方法

				// 未声明切入方法,则执行所有切入方法
				if (aspectName == null) {

					if (method.getName() != null) {
						if (method.getName().equals(elementMethod)) {
							getAllMethod(clazz, aspectClass, args);

						}

					}
					aspactAllClass(aspectClass, args==null? new Object[1]: args);
				} else {
					//if判断是否 声明l切入方法,若是则执行指定切入方法,否则执行所有方法
					if (method.getName().equals(elementMethod)) {
						Method jinectmethod = clazz.getMethod(aspectName, Object.class); // 反射调用切入类方法
						jinectmethod.invoke(aspectBeans.get(aspectClass), args==null? new Object[1]: args);
					}
					aspactAllClass(aspectClass, args==null? new Object[1]: args);
				}

			}

		}
		//传入集合对象为空,则执行多有对象的所有方法
		else {

			Iterator aspectClass = aspectBeans.entrySet().iterator();
			while (aspectClass.hasNext()) {
				Entry<String, Object> entry = (Entry<String, Object>) aspectClass.next();
				Class clazz = entry.getValue().getClass();// 获取切入类
				Method[] methods = clazz.getMethods();
				for (int j = 0; j < methods.length; j++) {
					// 读取切入类注解中的所有方法
					if (methods[j].isAnnotationPresent(MethodCatch.class) == true) {
						MethodCatch methodCatch = methods[j]
								.getAnnotation(MethodCatch.class);// 获取注解类
						Method jinectmethod = clazz.getMethod(methodCatch.methodName(),
								Object.class); // 反射调用切入类方法
						jinectmethod.invoke(entry.getValue(), args==null? new Object[1]: args);
					}

				}
			}
		}
	}

	/**
	 *
	* @Title: aspactAllClass
	* @Description:  执行容器中所有服务类中的方法(除了指定的对象不执行,其他的都执行)
	* @param @param aspectId
	* @param @param args
	* @param @throws NoSuchMethodException
	* @param @throws SecurityException
	* @param @throws IllegalAccessException
	* @param @throws IllegalArgumentException
	* @param @throws InvocationTargetException    设定文件
	* @return void    返回类型
	* @throws
	 */
	public void aspactAllClass(String aspectId, Object[] args)
			throws NoSuchMethodException, SecurityException, IllegalAccessException,
			IllegalArgumentException, InvocationTargetException {
		Iterator aspectClass = aspectBeans.entrySet().iterator();

		//while循环获取服务集合中的所有对象,调用该对象中的方法
		while (aspectClass.hasNext()) {
			Entry<String, Object> entry = (Entry<String, Object>) aspectClass.next();

			if (!aspectId.equals(entry.getKey())) {
				Class clazz = entry.getValue().getClass();// 获取切入类
				Method[] methods = clazz.getMethods();
				for (int j = 0; j < methods.length; j++) {
					// 读取切入类注解中的所有方法
					if (methods[j].isAnnotationPresent(MethodCatch.class) == true) {
						MethodCatch methodCatch = methods[j]
								.getAnnotation(MethodCatch.class);// 获取注解类
						Method jinectmethod = clazz.getMethod(methodCatch.methodName(),
								Object.class); // 反射调用切入类方法
						jinectmethod.invoke(entry.getValue(), args==null? new Object[1]: args);
					}

				}
			}
		}
	}

	/**
	 * 执行某个服务类中的所有方法
	* @Title: getAllMethod
	* @Description: TODO(这里用一句话描述这个方法的作用)
	* @param @param clazz
	* @param @param aspectClass
	* @param @param args
	* @param @throws IllegalAccessException
	* @param @throws IllegalArgumentException
	* @param @throws InvocationTargetException
	* @param @throws NoSuchMethodException
	* @param @throws SecurityException    设定文件
	* @return void    返回类型
	* @throws
	 */
	public void getAllMethod(Class clazz, String aspectClass, Object[] args)
			throws IllegalAccessException, IllegalArgumentException,
			InvocationTargetException, NoSuchMethodException, SecurityException {
		Method[] methods = clazz.getMethods();
		for (int j = 0; j < methods.length; j++) {

			if (methods[j].isAnnotationPresent(MethodCatch.class) == true) {
				MethodCatch methodCatch = methods[j].getAnnotation(MethodCatch.class);// 获取注解类
				Method jinectmethod = clazz.getMethod(methodCatch.methodName(),
						Object.class); // 反射调用切入类方法
				jinectmethod.invoke(aspectBeans.get(aspectClass), args==null? new Object[1]: args);
			}

		}
	}
}

UserDao:

package com.tgb.dao;

import com.tgb.domain.User;

/**
 * 用于操作用户信息类。
* @ClassName: UserDao
* @Description: TODO(这里用一句话描述这个类的作用)
* @author [qmx]
* @date
*
 */
public interface UserDao {

	void save(User user);

	void update(User user);

	public void delete( User user);

}

UserDaoImpl:

package com.tgb.daoImpl;

import com.tgb.dao.UserDao;
import com.tgb.domain.User;

/**
 * 用户操作类,用于添加用户信息
 *
 * @ClassName: UserDaoImpl
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author [qmx]
 * @date
 *
 */
public class UserDaoImpl implements UserDao {

	@Override
	public void save(User user) {
		System.out.println("这是业务类 " + this.getClass()
				+ "-----的 userDao.save()方法-----");

	}

	@Override
	public void update(User user) {
		System.out.println("这是业务类 " + this.getClass()
				+ "-----的 userDao.update()方法-----");

	}

	@Override
	public void delete(User user) {
		System.out.println("这是业务类 " + this.getClass()
				+ "-----的 userDao.delete()方法-----");

	}

}

User:

package com.tgb.domain;

public class User {

	private String userName;
	private String password;
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}

}

MethodCatch:

package com.tgb.util;

/**
 * 自定义注解类,用于类方法上读取方法名称
 */
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodCatch {

	/**
	 * 用于 获取方法名称
	* @Title: methodName
	* @Description:
	* @param @return    设定文件
	* @return String    返回类型
	* @throws
	 */
	public String methodName();
}

aspectbeans.xml:

<beans>
<!-- 服务类配置 -->
	<aspectbean id="aspectCachBean" class="com.tgb.config.AspectCachBean"></aspectbean>
	<aspectbean id="aspectCertifiyBean" class="com.tgb.config.AspectCertifiyBean"></aspectbean>
</beans>

beans.xml:

<beans>
<!-- 业务类 -->
	<bean id="UserDao" class="com.tgb.daoImpl.UserDaoImpl" />

	<!-- 是否启用aop -->
	<aop isaop="true"></aop>

<!-- 关系配置 -->
 <!-- aspectMethod="save"  -->
	<aspectbefore  aspectId="aspectCachBean" method="update"  aspectMethod="cacheAfter" ></aspectbefore>
	<aspectbefore  aspectId="aspectCertifiyBean" method="update"  aspectMethod="certifyAfter" ></aspectbefore>
</beans>
时间: 2024-10-09 03:34:16

动态代理实现Spring Aop的相关文章

从动态代理到Spring AOP(上)

一.前言 虽然平时日常开发很少用到动态代理,但是动态代理在底层框架等有着非常重要的意义.比如Spring AOP使用cglib和JDK动态代理,Hibernate底层使用了javassit和cglib动态代理,Dubbo使用javassist字节码(具体可以看Dubbo SPI). 本文主要介绍什么是动态代理及原理,下文将介绍Spring AOP 我们先思考一个问题:如何统计一个类各个方法的执行时间?可能你心里有好多答案都可以解决问题. 那么如果是这个项目的多个不同类呢?可能心里也有答案,但是代

【设计模式】代理模式:静态代理,动态代理,spring aop

代理模式分为静态代理和动态代理.我们拿链家来举例子,我们本人是真实的对象,有真实的业务需求:需要去找房子:链家是中介,是代理类,他来帮我执行找房子的这个操作. 静态代理: 1.实现一个接口 public interface SearchHome { public void search(); } 2.构建实现接口的委托类 public class Master implements SearchHome { @Override public void search() { System.out.

反射实现AOP动态代理模式(Spring AOP实现原理)

其实AOP的意思就是面向切面编程. OO注重的是我们解决问题的方法(封装成Method),而AOP注重的是许多解决问题的方法中的共同点,是对OO思想的一种补充! 还是拿人家经常举的一个例子讲解一下吧: 比如说,我们现在要开发的一个应用里面有很多的业务方法,但是,我们现在要对这个方法的执行做全面监控,或部分监控.也许我们就会在要一些方法前去加上一条日志记录. 我们写个例子看看我们最简单的解决方案 我们先写一个接口IHello.java代码如下: package sinosoft.dj.aop.st

jdk动态代理与cglib代理、spring aop代理实现原理解析

原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主 代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 动态代理实现主要有2种形式,主要分为: 1.jdk动态代理: 1)原理:是根据类加载器和接口创建代理类(此代理类是接口的实现类,所以必须使用接口 面向接口生成代理,位于java.lang.reflect包下) 2)实现方式: 1. 通过实现Invocati

AOP、静态代理、JDK动态代理、CGLIB动态代理、Spring实现AOP、IOC+AOP

一.为什么需要代理模式 假设需实现一个计算的类Math.完成加.减.乘.除功能,如下所示: 1 package com.zhangguo.Spring041.aop01; 2 3 public class Math { 4 //加 5 public int add(int n1,int n2){ 6 int result=n1+n2; 7 System.out.println(n1+"+"+n2+"="+result); 8 return result; 9 } 1

动态代理的应用---AOP

1. AOP:面向切面编程 2. 实现原理:动态代理 3. 配置方式: <1> @AspectJ <2> XML 推荐<2>,原因:可实现"热插拔". 4. 相关术语介绍 <1> 切面:aspect 需要实现的交叉功能----通知和切入点的结合. 通知和切入点共同定义了关于前面的全部功能:它的功能.在何时和何地完成功能. <2> 通知: advice 定义了切面是什么以及何时使用. 描述的内容:切面需要完成的工作.何时执行该工

Java代理及Spring AOP

Spring的AOP核心采用的设计模式采用的是代理模式,先介绍下Java的代理. 这里借鉴一下其他人的介绍,https://blog.csdn.net/fighterandknight/article/details/51200470 一 代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身

动态代理模式和AOP探究

java强大的反射机制给动态代理带来了可能.能够自由穿梭在类与方法之间.简直神通广大. 动态代理的一个小例子,顺便看看神奇的AOP是如何实现的.代码如下: 首先声明的是一个接口Dog类 1 package com.chenjun.test; 2 3 public interface Dog 4 { 5 public void info(); 6 public void run(); 7 } 然后一个“猎狗类”实现了该接口 1 package com.chenjun.test; 2 3 publi

java动态代理与老式AOP实现

JAVA的动态代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. 按照代理的创建时期,代理类可以分为两种. class文件就已经存在了. 动态代理:在程序运行时,运用反射机制动态创建而成. 首先看一下静态代理: /** *