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());
  • 相关阅读:
    创建git项目的feature分支以及下载特定分支的仓库代码
    C++读取文件
    linux解压eclipse启动时无法找到jre环境的解决办法
    ubuntu安装谷歌浏览器
    web项目脱离Eclipse在Tomcat部署并配置Eclipse调试
    阿里巴巴连接池Druid简单使用
    gc overhead limit exceeded
    onload方法注意点
    获取Spring管理的Bean
    Java应用中使用ShutdownHook友好地清理现场
  • 原文地址:https://www.cnblogs.com/orlion/p/5350859.html
Copyright © 2011-2022 走看看