Spring_AOP_Proxy AOP动态代理的实现

Spring_AOP_Proxy AOP动态代理的实现 :

动态代理指的是通过一个代理对象来创建需要的业务对象,然后在这个代理对象中统一进行各种需求的处理。
1.写一个实现相应的InvocationHandler 接口
2.创建要代理的对象

3.创建一个方法生成对象,这个方法的参数是要代理的对象,getInstance 所返回的对象就是代理对象

3.1 创建LogProxy对象

3.2设置这个代理对象

3.3 通过Proxy的方法创建代理对象,

第一个参数是要代理对象的classLoader第二个参数是要代理对象实现的所有接口,

第三个参数是实现类InvocationHander 的对象此时的result就是一个代理的对象,代理的是object

具体实现过程:

Spring_AOP_Proxy AOP静态代理的实现 的基础上,修改log包名为proxy,并创建LogProxy代理类并实现接口InvocationHandler:

package com.spring.proxy;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;

import com.spring.model.LogInfo;

/**
 * 1.写一个类实现InvocationHandler 接口
 * 
 * @author sunlight
 *
 */
public class LogProxy implements InvocationHandler {

	// 2.创建一个代理对象
	private Object target;

	// 3.创建一个方法生成对象,这个方法的参数是要代理的对象,getInstance 所返回的对象就是代理对象
	public static Object getInstance(Object object) {

		// 3.1 创建LogProxy对象
		LogProxy proxy = new LogProxy();

		// 3.2设置这个代理对象
		proxy.target = object;

		// 3.3 通过Proxy的方法创建代理对象,第一个参数是要代理对象的classLoader
		// 第二个参数是要代理对象实现的所有接口,第三个参数是实现类InvocationHander 的对象
		// 此时的result就是一个代理的对象,代理的是object
		Object result = Proxy.newProxyInstance(object.getClass()
				.getClassLoader(), object.getClass().getInterfaces(), proxy);
		return result;
	}

	/**
	 * 当有了代理对象之后,不管这个代理对象执行什么方法,都会调用以下的invoke方法
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {

		if (method.getName().equals("add") || method.getName().equals("delete")
				|| method.getName().equals("update")) {
			Logger.info("进行了相应的操作——通过方法名称(方法执行前)");
		}

		Object obj = method.invoke(target, args);
		
		if(method.isAnnotationPresent(LogInfo.class)){
			LogInfo li=method.getAnnotation(LogInfo.class);
			Logger.info(li.value()+"(方法执行后)");
		}
		
		return obj;
	}

}

修改配置文件,添加LogProxy的注入:

<?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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
	
	<!-- 打开Spring的Annotation的支持 -->
	<context:annotation-config />
	<!-- 设定Spring去哪些包中找Annotation -->
	<context:component-scan base-package="com.spring" />
	
	<bean id="userDynamicDao" class="com.spring.proxy.LogProxy" factory-method="getInstance">
		<constructor-arg ref="userDao"/>
	</bean>
	
</beans>

修改UserService注入userDynamicDao:

package com.spring.service;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import com.spring.dao.IUserDao;
import com.spring.model.User;

//@Component(value="userService")
@Service("userService")		//业务层一般用@Service注入
public class UserService implements IUserService {
	private IUserDao userDao;
	
	public IUserDao getUserDao() {
		return userDao;
	}
	
	//默认通过名称注入,在JSR330中提供了@Inject来注入
	//@Resource(name="userProxyDao")	//此处用代理类注入
	@Resource(name="userDynamicDao")
	public void setUserDao(IUserDao userDao) {
		this.userDao = userDao;
	}

	@Override
	public void add(User user) {
		userDao.add(user);
	}

	@Override
	public void delete(int id) {
		userDao.delete(id);
	}

	@Override
	public User load(int id) {
		return userDao.load(id);
	}

}



编写简单的注解 LogInfo:

package com.spring.model;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface LogInfo {
	public String value() default "";
}

IUserDao接口添加注解,添加了LogInfo注解的方法可以为其添加日志。
package com.spring.dao;

import com.spring.model.LogInfo;
import com.spring.model.User;

public interface IUserDao {
	@LogInfo("添加了用户信息——注解方式")
	public void add(User user);
	@LogInfo("删除了用户信息——注解方式")
	public void delete(int id);
	public User load(int id);
}

以上是动态代理的2中实现:

1.通过方法名称来添加日志;

2.通过注解方式来添加日志;

注意,AOP的动态代理实现,添加日志操作可以在方法执行前,也可以在方法执行后,本例 方法前使用 1 来添加日志,方法后使用 2 来添加日志。

测试结果如下:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值