• 使用代理为业务操作添加安全检测


     

    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", "dennisit@163.com");
            
            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]

    在线交谈

     

  • 相关阅读:
    mysql启动错误
    maven环境变量配置
    记一次服务器Tomcat优化经历
    自动定时备份删除脚本
    Tomcat网页加载速度过慢的解决方法
    tomcat运行war包报错,找不到context-root文件
    maven下配置pom.xml
    [LeetCode]题解(python):116-Populating Next Right Pointers in Each Node
    [LeetCode]题解(python):115-Distinct Subsequences
    [LeetCode]题解(python):114-Flatten Binary Tree to Linked List
  • 原文地址:https://www.cnblogs.com/dennisit/p/2913272.html
Copyright © 2020-2023  润新知