1.使用静态代理为系统操作添加安全性检查
实例结构图
业务接口定义
package com.dennist.dao; public interface UserDao { public void addUser(String name, String password); public void deleteUser(int id); public void updateUser(int id, String name, String password); public String queryUser(int id); }
接口的实现
package com.dennist.dao.impl; import com.dennist.dao.UserDao; public class UserDaoImpl implements UserDao{ @Override public void addUser(String name, String password) { System.out.println("UserDaoImpl.addUser()"); } @Override public void deleteUser(int id) { System.out.println("UserDaoImpl.deleteUser()"); } @Override public String queryUser(int id) { System.out.println("UserDaoImpl.queryUser()"); return null; } @Override public void updateUser(int id, String name, String password) { System.out.println("UserDaoImpl.updateUser()"); } }
使用静态代理添加安全性检测
package com.dennist.dao.impl; import com.dennist.dao.UserDao; public class UserDaoImplProxy implements UserDao{ private UserDao userDao; public UserDaoImplProxy(UserDao userDao){ this.userDao = userDao; } @Override public void addUser(String name, String password) { checkSecurity(); this.userDao.addUser(name, password); } @Override public void deleteUser(int id) { checkSecurity(); this.userDao.deleteUser(id); } @Override public String queryUser(int id) { checkSecurity(); return this.userDao.queryUser(id); } @Override public void updateUser(int id, String name, String password) { checkSecurity(); this.userDao.updateUser(id, name, password); } public void checkSecurity(){ System.out.println("---------checkSecurity---------"); } }
客户端测试代码
package com.dennist.client; import com.dennist.dao.UserDao; import com.dennist.dao.impl.UserDaoImpl; import com.dennist.dao.impl.UserDaoImplProxy; public class ClientOpt { public static void main(String[] args) { UserDao userDao = new UserDaoImpl(); UserDaoImplProxy userDaoImplProxy = new UserDaoImplProxy(userDao); userDaoImplProxy.addUser("dennisit", "[email protected]"); userDaoImplProxy.deleteUser(5); } } 运行结果: ---------checkSecurity--------- UserDaoImpl.addUser() ---------checkSecurity--------- UserDaoImpl.deleteUser()
2.使用JDK的动态代理
需要实现java.lang.reflect.InvocationHandler接口
实例结构图
业务接口定义与实现同上,JDK代理实现代码如下
package com.dennist.dao.impl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class SecurityHandler implements InvocationHandler{ private Object targetObject; public Object newProxy(Object targetObject){ this.targetObject = targetObject; //面向接口编程,安全认证加在接口上.
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { checkSecurity(); Object result = null; try { result = method.invoke(this.targetObject, args); } catch (Exception e) { e.printStackTrace(); } return result; } public void checkSecurity(){ System.out.println("---------checkSecurity---------"); } }
客户端测试代码
package com.dennist.client; import com.dennist.dao.UserDao; import com.dennist.dao.impl.SecurityHandler; import com.dennist.dao.impl.UserDaoImpl; public class ClientOpt { public static void main(String[] args) { SecurityHandler handler = new SecurityHandler(); UserDao userDao = (UserDao) handler.newProxy(new UserDaoImpl()); userDao.addUser("zhangan", "pwd123"); userDao.deleteUser(5); } } 运行结果: ---------checkSecurity--------- UserDaoImpl.addUser() ---------checkSecurity--------- UserDaoImpl.deleteUser()
3.使用springAOP动态织入(使用xml配置)
springAOP默认采用JDK的动态代理.
项目结构图
业务dao与dao实现同上
定义安全检测方法
package com.spring.dao.impl; public class SecurityHandler { public void checkSecurity() { System.out.println("----------checkSecurity()---------------"); } }
applicationContext.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="securityHandler" class="com.spring.dao.impl.SecurityHandler"/>
<bean id="userDao" class="com.spring.dao.impl.UserDaoImpl"/>
<aop:config>
<aop:aspect id="securityAspect" ref="securityHandler">
<aop:pointcut id="allAddMethod" expression="execution(* query*(..))||execution(* add*(..))"/>
<aop:before pointcut-ref="allAddMethod" method="checkSecurity"/>
</aop:aspect>
</aop:config>
</beans>
客户端测试
package com.spring.client; import org.springframework.beans.factory.BeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.spring.dao.UserDao; public class ClientOpt { public static void main(String[] args) { BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = (UserDao) factory.getBean("userDao"); userDao.addUser("zhangsan", "pwd123"); System.out.println(""); userDao.deleteUser(5); System.out.println(""); userDao.queryUser(3); } } 运行效果: ----------checkSecurity()--------------- UserDaoImpl.addUser() UserDaoImpl.deleteUser() ----------checkSecurity()--------------- UserDaoImpl.queryUser()
spring对AOP的支持
如果目标对象实现了接口,默认会采用JDK的动态代理机制实现AOP
如果目标对实现了接口,可以强制使用CGLIB实现AOP
如果目标对象没有实现接口,必须使用CGLIB生成代理,spring会自动在CGLIB和JDK动态代理之间切换.
如何强制使用CGLIB生成代理?
1.添加CGLIB库
2.在spring的配置文件中加入:<aop:aspectj-autoproxy proxy-target-class="true"/>
JDK代理和CGLIB代理的区别?
JDK代理只能对实现了接口的类生成代理,而不能针对类
CGLIB是针对类实现代理的,主要对指定的类生成一个子类,并覆盖其中的方法,因为是继承,所以不能使用final来修饰类或方法.
转载请注明出处:[http://www.cnblogs.com/dennisit/archive/2013/02/16/2913272.html]