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:

  1. package com.spring.proxy;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import org.springframework.cglib.proxy.InvocationHandler;  
  6. import org.springframework.cglib.proxy.Proxy;  
  7.   
  8. import com.spring.model.LogInfo;  
  9.   
  10. /** 
  11.  * 1.写一个类实现InvocationHandler 接口 
  12.  *  
  13.  * @author sunlight 
  14.  * 
  15.  */  
  16. public class LogProxy implements InvocationHandler {  
  17.   
  18.     // 2.创建一个代理对象   
  19.     private Object target;  
  20.   
  21.     // 3.创建一个方法生成对象,这个方法的参数是要代理的对象,getInstance 所返回的对象就是代理对象   
  22.     public static Object getInstance(Object object) {  
  23.   
  24.         // 3.1 创建LogProxy对象   
  25.         LogProxy proxy = new LogProxy();  
  26.   
  27.         // 3.2设置这个代理对象   
  28.         proxy.target = object;  
  29.   
  30.         // 3.3 通过Proxy的方法创建代理对象,第一个参数是要代理对象的classLoader   
  31.         // 第二个参数是要代理对象实现的所有接口,第三个参数是实现类InvocationHander 的对象   
  32.         // 此时的result就是一个代理的对象,代理的是object   
  33.         Object result = Proxy.newProxyInstance(object.getClass()  
  34.                 .getClassLoader(), object.getClass().getInterfaces(), proxy);  
  35.         return result;  
  36.     }  
  37.   
  38.     /** 
  39.      * 当有了代理对象之后,不管这个代理对象执行什么方法,都会调用以下的invoke方法 
  40.      */  
  41.     @Override  
  42.     public Object invoke(Object proxy, Method method, Object[] args)  
  43.             throws Throwable {  
  44.   
  45.         if (method.getName().equals("add") || method.getName().equals("delete")  
  46.                 || method.getName().equals("update")) {  
  47.             Logger.info("进行了相应的操作——通过方法名称(方法执行前)");  
  48.         }  
  49.   
  50.         Object obj = method.invoke(target, args);  
  51.           
  52.         if(method.isAnnotationPresent(LogInfo.class)){  
  53.             LogInfo li=method.getAnnotation(LogInfo.class);  
  54.             Logger.info(li.value()+"(方法执行后)");  
  55.         }  
  56.           
  57.         return obj;  
  58.     }  
  59.   
  60. }  
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的注入:

  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  5.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">  
  6.       
  7.     <!-- 打开Spring的Annotation的支持 -->  
  8.     <context:annotation-config />  
  9.     <!-- 设定Spring去哪些包中找Annotation -->  
  10.     <context:component-scan base-package="com.spring" />  
  11.       
  12.     <bean id="userDynamicDao" class="com.spring.proxy.LogProxy" factory-method="getInstance">  
  13.         <constructor-arg ref="userDao"/>  
  14.     </bean>  
  15.       
  16. </beans>  
<?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:

  1. package com.spring.service;  
  2.   
  3. import javax.annotation.Resource;  
  4.   
  5. import org.springframework.stereotype.Component;  
  6. import org.springframework.stereotype.Service;  
  7.   
  8. import com.spring.dao.IUserDao;  
  9. import com.spring.model.User;  
  10.   
  11. //@Component(value="userService")   
  12. @Service("userService")     //业务层一般用@Service注入   
  13. public class UserService implements IUserService {  
  14.     private IUserDao userDao;  
  15.       
  16.     public IUserDao getUserDao() {  
  17.         return userDao;  
  18.     }  
  19.       
  20.     //默认通过名称注入,在JSR330中提供了@Inject来注入   
  21.     //@Resource(name="userProxyDao")    //此处用代理类注入   
  22.     @Resource(name="userDynamicDao")  
  23.     public void setUserDao(IUserDao userDao) {  
  24.         this.userDao = userDao;  
  25.     }  
  26.   
  27.     @Override  
  28.     public void add(User user) {  
  29.         userDao.add(user);  
  30.     }  
  31.   
  32.     @Override  
  33.     public void delete(int id) {  
  34.         userDao.delete(id);  
  35.     }  
  36.   
  37.     @Override  
  38.     public User load(int id) {  
  39.         return userDao.load(id);  
  40.     }  
  41.   
  42. }  
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:

  1. package com.spring.model;  
  2.   
  3. import java.lang.annotation.Retention;  
  4. import java.lang.annotation.RetentionPolicy;  
  5.   
  6. @Retention(RetentionPolicy.RUNTIME)  
  7. public @interface LogInfo {  
  8.     public String value() default "";  
  9. }  
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注解的方法可以为其添加日志。
  1. package com.spring.dao;  
  2.   
  3. import com.spring.model.LogInfo;  
  4. import com.spring.model.User;  
  5.   
  6. public interface IUserDao {  
  7.     @LogInfo("添加了用户信息——注解方式")  
  8.     public void add(User user);  
  9.     @LogInfo("删除了用户信息——注解方式")  
  10.     public void delete(int id);  
  11.     public User load(int id);  
  12. }  
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 来添加日志。

测试结果如下:



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值