zoukankan      html  css  js  c++  java
  • Spring(三)AOP面向切面编程

    原文链接:http://www.orlion.ga/205/

    一、AOP简介

    1、AOP概念

        参考文章:http://www.orlion.ml/57

    2、AOP的产生

        对于如下方法:

        public class UserDAOImpl implements UserDAO{
        
        	public void saveUser(User user){
        		doSaveUser();
        	}
        }

        想在saveUser方法中执行保存用户之前和之后记录当前时间以求出saveUser花费了多少时间,方法有很多种,最直观的写法就是在doSaveUser()前后加代码取出当前时间:

        public class UserDAOImpl implements UserDAO{
        
        	public void saveUser(User user){
        		int beginTime = getCurrentTime();
        		
        		doSaveUser();
        		
        		int endTime = getCurrentTime();
        	}
        }

        还有一种方法就是重新写一个类继承自UserDAOImpl然后重写saveUser方法,如下:

        public class UserDAOImpl2 extends UserDAOImpl{
            @Override
    	public void saveUser(User user){
    		int beginTime = getCurrentTime();
    		
    		super.saveUser();
    		
    		int endTime = getCurrentTime();
    	}
        }

        这种方法耦合性太强,一旦父类改变了子类也会改变,慎用继承

        再有一种方法就是在调用saveUser()方法时加代码:

        

        public class UserService{
            
    	public void saveUser(User user){
    	        UserDAOImpl userDao = new UserDAOImpl();
    		int beginTime = getCurrentTime();
    		
    		userDao.saveUser();
    		
    		int endTime = getCurrentTime();
    	}
        }

        

        现在如果让我们将项目中所有的对数据库进行CRUD操作的方法都加上获取时间的代码,显然工作量太大,这时候就用动态代理: (可参考http://www.orlion.ml/207/)

        UserDAOImpl.java

        package ml.orlion.dao.impl;
        
        import ml.orlion.dao.UserDAO;
        import ml.orlion.model.User;
        
        public class UserDAOImpl implements UserDAO{
        
        	public void saveUser(User user){
        		System.out.println("save usering");
        	}
        }

        TimeInterceptor.java

        package ml.orlion.aop;
        
        import java.lang.reflect.InvocationHandler;
        import java.lang.reflect.Method;
        
        public class TimeInterceptor implements InvocationHandler{
        	
        	private Object target;// 被代理的对象
        	
        	public Object getTarget() {
        		return target;
        	}
        	public void setTarget(Object target) {
        		this.target = target;
        	}
        	public void beforeMethod(Method m){
        		System.out.println(m.getName() + "begin start");
        	}
        	@Override
        	public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
        		
        		this.beforeMethod(m);// 插入方法
        		m.invoke(target, args);
        		return null;
        	}
        }

        测试

        public static void testProxy(){
    	// 首先产生一个被代理对象
    	UserDAO userDao = new UserDAOImpl();
    	// 下一步将被代理对象交给InvocationHandler即TimeInterceptor
    	TimeInterceptor ti = new TimeInterceptor();
    	// 设置被代理对象
    	ti.setTarget(userDao);
    	// 根据被代理对象产生一个代理
    	UserDAO userProxy = (UserDAO)Proxy.newProxyInstance(UserDAO.class.getClassLoader(), new Class[]{UserDAO.class}, ti);
    	userProxy.saveUser(new User());
        }

        运行可以看到控制台打印:saveUserbegin start      save usering

    二、使用Spring AOP

    UserDAO.java:

    package ml.orlion.dao;
    
    import ml.orlion.model.User;
    
    public interface UserDAO {
    	public void saveUser(User user);
    }

    UserDAOImpl.java:

    package ml.orlion.dao.impl;
    
    import ml.orlion.dao.UserDAO;
    import ml.orlion.model.User;
    
    public class UserDAOImpl implements UserDAO{
    
    	public void saveUser(User user){
    		System.out.println("save usering");
    	}
    }

    UserService.java

    package ml.orlion.service;
    
    import ml.orlion.dao.UserDAO;
    import ml.orlion.dao.impl.UserDAOImpl;
    import ml.orlion.model.User;
    
    public class UserService {
    
    	private UserDAO userDAO = new UserDAOImpl();
    
    	public UserDAO getUserDao() {
    		
    		return userDAO;
    	}
    
    	public void setUserDao(UserDAO userDAO) {
    		this.userDAO = userDAO;
    	}
    	
    	public void saveUser(User user){
    		this.userDAO.saveUser(user);
    	}
    }

    LogInterceptor.java

    package ml.orlion.aop;
    
    public class LogInterceptor {
    
    	public void before(){
    		System.out.println("before");
    	}
    }

    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:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop.xsd">
    	
    	<bean id="logInterceptor" class="ml.orlion.aop.LogInterceptor">
    	</bean>
      	<bean id="userDao" class="ml.orlion.dao.impl.UserDAOImpl">
     	
      	</bean>
      	<bean id="userService" class="ml.orlion.service.UserService">
      		<property name="userDao" ref="userDao"/>
      	</bean>
      	<aop:config>
      		<aop:pointcut expression="execution(public * ml.orlion.service..*.add(..))"
      			id="servicePointcut" />
      		<aop:aspect id="logAspect" ref="logInterceptor">
      			<aop:before method="before" pointcut-ref="servicePointcut"/>
      		</aop:aspect>
      	</aop:config>
    </beans>

    测试:

    BeanFactory appContext = new ClassPathXmlApplicationContext("beans.xml");
    UserService userService = (UserService) appContext.getBean("userService");
    userService.saveUser(new User());
  • 相关阅读:
    docker 安装mysql
    Java web项目搭建系列之二 Jetty下运行项目
    Java web项目搭建系列之一 Eclipse中新建Maven项目
    Maven 添加其他Maven组件配置问题
    C# 中定义扩展方法
    Oracle 函数
    【Webservice】2 counts of IllegalAnnotationExceptions Two classes have the same XML type name
    Linux精简版系统安装网络配置问题解决
    Rsync 故障排查整理
    Failed to set session cookie. Maybe you are using HTTP instead of HTTPS to access phpMyAdmin.
  • 原文地址:https://www.cnblogs.com/orlion/p/5350859.html
Copyright © 2011-2022 走看看