论坛首页 Java企业应用论坛

Spring原理自我实践之AOP的实现原理

浏览 5154 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (9) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-08-21   最后修改:2009-08-21
AOP的简单描述:
      面向切面的编程,针对系统中与核心业务关系不是那么紧密的功能。 诸如事务、安全验证、日志等,通过一种机制,将他们分离, 这样能够减弱代码的耦合 ,使逻辑可以清晰分离
        实现的方式有三种:
       1.编译期间,由java文件生成class文件过程中加入
       2.类加载器,由class文件加载到内存过程中加入
       3.动态代理和cglib
主要的源码:
package com.erong.spring.aop.myaop;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.framework.ProxyFactory;

 
public class Main {

	/**实例说明:
	 * 通过AOP对模拟系统的注册和登录生成日志打印在控制台
	 * 每次调用到creat()和login()都会生成日志
	 * 在代码中没有任何的日志代码
	 * @param args
	 */
	public static void main(String[] args) {

		UserDao userDao = new UserDao();
		UserServiceImpl target = new UserServiceImpl();//创建要拦截的对象
		target.setUserDao(userDao);

		MethodBeforeAdvice log = new MethodBeforeAdvice() {
			public void before(Method m, Object[] args, Object target)
					throws Throwable {
				System.out.println("调用方法: " + m.getName());
			}
		};
		
		 

		// UserService userService =
		// (UserService)AopProxyFactory.createProxy(target, log);
	 	ProxyFactory factory = new ProxyFactory(target);
	 	factory.addAdvice(log);
		UserService userService = (UserService) factory.getProxy();
		userService.create("aop", "mypassword");
	 
		userService.login("aop", "mypassword");
        userService.getAllUser();
	//	userDao.print();
	}
}

模拟的底层DAO

package com.erong.spring.aop.myaop;

import java.util.*;

/**
 * 模拟底层DAO
 * 
 * @author citizen
 * 
 */
public class UserDao {

	private Map<String, String> map = new HashMap<String, String>();

	public UserDao() {
		map.put("admin", "security");
		map.put("test", "123456");
	}

	public Map<String, String> getUserMap() {
		System.out.println("用户名列表:");
		Set<String> keySet = map.keySet();
		for (String key : keySet) {
			System.out.println(key + " " + map.get(key));
		}
		return this.map;
	}

	/**
	 * 模拟创建用户
	 * 
	 * @param username
	 * @param password
	 */
	public void create(String username, String password) {
		if (map.get(username) != null)
			throw new RuntimeException("添加失败,用户已存在User exist!");
		map.put(username, password);
	}

	/**
	 * 模拟登录
	 * 
	 * @param username
	 * @param password
	 */
	public void login(String username, String password) {
		String pw = map.get(username);
		if (pw == null || !pw.equals(password))
			throw new RuntimeException("登录失败 Login failed.");
	}

	/**
	 * 打印出目前已有的用户信息
	 */
	public void print() {
		System.out.println("用户名列表:");
		Set<String> keySet = map.keySet();
		for (String key : keySet) {
			System.out.println(key + " " + map.get(key));
		}
	}
}

定义的服务接口:

package com.erong.spring.aop.myaop;

import java.util.Map;

/**服务接口
 * @author citizen
 *
 */
public interface UserService {

    void create(String username, String password);

    void login(String username, String password);
    
    Map<String , String> getAllUser();
}

实现服务接口的实现类:
package com.erong.spring.aop.myaop;

import java.util.Map;

/**服务实现类
 * @author citizen
 *
 */
public class UserServiceImpl implements UserService {

    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void create(String username, String password) {
        userDao.create(username, password);
    }

    public void login(String username, String password) {
        userDao.login(username, password);
    }

	@Override
	public Map<String, String> getAllUser() {
		// TODO Auto-generated method stub
		return userDao.getUserMap();
	}

}


模拟客户端:

 
package com.erong.spring.aop.myaop;

import java.util.*;

/**
 * 模拟底层DAO
 * 
 * @author citizen
 * 
 */
public class UserDao {

	private Map<String, String> map = new HashMap<String, String>();

	public UserDao() {
		map.put("admin", "security");
		map.put("test", "123456");
	}

	public Map<String, String> getUserMap() {
		System.out.println("用户名列表:");
		Set<String> keySet = map.keySet();
		for (String key : keySet) {
			System.out.println(key + " " + map.get(key));
		}
		return this.map;
	}

	/**
	 * 模拟创建用户
	 * 
	 * @param username
	 * @param password
	 */
	public void create(String username, String password) {
		if (map.get(username) != null)
			throw new RuntimeException("添加失败,用户已存在User exist!");
		map.put(username, password);
	}

	/**
	 * 模拟登录
	 * 
	 * @param username
	 * @param password
	 */
	public void login(String username, String password) {
		String pw = map.get(username);
		if (pw == null || !pw.equals(password))
			throw new RuntimeException("登录失败 Login failed.");
	}

	/**
	 * 打印出目前已有的用户信息
	 */
	public void print() {
		System.out.println("用户名列表:");
		Set<String> keySet = map.keySet();
		for (String key : keySet) {
			System.out.println(key + " " + map.get(key));
		}
	}
}



AOP的代理工厂:

package com.erong.spring.aop.myaop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.springframework.aop.MethodBeforeAdvice;

/**AOP代理工厂
 * @author citizen
 *
 */
public class AopProxyFactory {

    /**创建代理
     * @param target
     * @param methodBeforeAdvice
     * @return
     */
    public static Object createProxy(final Object target, final MethodBeforeAdvice methodBeforeAdvice) {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new InvocationHandler() {//匿名内部类
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        methodBeforeAdvice.before(method, args, target);
                        return method.invoke(target, args);
                    }
                });
    }
}
   发表时间:2009-08-21  
AOP 到底是个什么? 还没搞清楚
  struts2+sprping+hibernate 集成时候,为何action类个不用继承接口
0 请登录后投票
   发表时间:2009-08-21  
skcmm 写道
AOP 到底是个什么? 还没搞清楚
  struts2+sprping+hibernate 集成时候,为何action类个不用继承接口

莫非连AOP都没弄清楚,你都开始SSH集成了?
0 请登录后投票
   发表时间:2009-08-24  
   是呀·, 有点迷惑,似懂非懂的样子·
   看了点资料  就赶鸭子上架 没办法 现在压力大呀
0 请登录后投票
   发表时间:2009-10-13  
skcmm 写道
   是呀·, 有点迷惑,似懂非懂的样子·
   看了点资料  就赶鸭子上架 没办法 现在压力大呀

如果你只是写一半的WEB开发,不懂aop也不是很重要,但是如果你想深造,以后还是需要学习的
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics