代理(Proxy)是一种设计模式,通过访问代理对象访问目标对象,好处:可以在实现目标对象功能的基础上,增加额外的功能,并且不修改已经写好的代码。
代理类:
public class LogProxy implements InvocationHandler{
private Object target;
public static Object getInstance(Object target) {
LogProxy LogProxy=new LogProxy();
LogProxy.target=target;
Object obj=Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), LogProxy);
//第三个参数是实现了InvocationHandler的对象
return obj;//返回代理对象
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO 自动生成的方法存根】
//只要一执行代理对象的方法,就会进入invoke方法
if(method.isAnnotationPresent(LogInfo.class)) {//判断该方法是否有annotation存在
//(通过判断该方法的接口IUserDao)
LogInfo li=method.getAnnotation(LogInfo.class);//获取Annotation
Logger.info(new Date()+","+li.value());//获取Annotation的value
}
Object result=method.invoke(target, args);//执行的是目标对象target的方法
return result;//执行该方法的返回值
}
}
beans.xml:
<?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.xsd">
<context:annotation-config/>
<context:component-scan base-package="spring"/>
<bean id="UserDynamicDao" class="spring.proxy.LogProxy" factory-method="getInstance">
<constructor-arg ref="UserDao"/>
</bean>
</beans>
<bean id="UserDynamicDao" class="spring.proxy.LogProxy" factory-method="getInstance">
<constructor-arg ref="UserDao"/>
</bean>
LogInfo(annotation):
@Retention(RetentionPolicy.RUNTIME)
public @interface LogInfo {
public String value() default "";
}
注意:(1)要加上@Retention(RetentionPolicy.RUNTIME)
IUserDao(加入annotation的value):
public interface IUserDao {
@LogInfo("add")
public void add(User user);
@LogInfo("delete")
public void delete(int id);
public User load(int id);
}
在service中注入动态dao:
@Resource(name="UserDynamicDao")
public void setUserDao(IUserDao userDao) {
UserDao = userDao;
}