码迷,mamicode.com
首页 > 编程语言 > 详细

[Spring系列02]Spring AOP模拟

时间:2015-03-03 20:27:34      阅读:148      评论:0      收藏:0      [点我收藏+]

标签:

 在博文[Spring系列01]Spring IOC/DI模拟中简略模拟了Spring IOC/DI的实现原理,本文接着模拟了Spring AOP的实现原理。

代码结构图如下:

技术分享

全部代码如下:

UserDAO.java

技术分享
package com.ctsh.dao;
import com.ctsh.model.User;


public interface UserDAO {
    public void save(User user);
    public void delete();
}
UserDAO

UserDAOImpl.java

技术分享
package com.ctsh.dao.impl;

import com.ctsh.dao.UserDAO;
import com.ctsh.model.User;


public class UserDAOImpl implements UserDAO {

    public void save(User user) {
        
        //Hibernate
        //JDBC
        //XML
        //NetWork
        System.out.println("user saved!");
    }

    public void delete() {
        System.out.println("user deteleted");
        
    }

}
UserDAOImpl

User.java

技术分享
package com.ctsh.model;

public class User {
    private String username;
    private String password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}
User

UserService.java

技术分享
package com.ctsh.service;

import com.ctsh.dao.UserDAO;
import com.ctsh.model.User;

public class UserService {
    private UserDAO userDAO;

    public void add(User user) {
        userDAO.save(user);
    }

    public UserDAO getUserDAO() {
        return userDAO;
    }

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }
}
UserService

BeanFactory.java

技术分享
package com.ctsh.spring;

public interface BeanFactory {
    public Object getBean(String id);
}
BeanFactory

ClassPathXmlApplicationContext.java

技术分享
package com.ctsh.spring;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;

public class ClassPathXmlApplicationContext implements BeanFactory {

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

    // IOC Inverse of Control DI Dependency Injection
    public ClassPathXmlApplicationContext() throws Exception {
        SAXBuilder sb = new SAXBuilder();

        Document doc = sb.build(this.getClass().getClassLoader()
                .getResourceAsStream("beans.xml"));
        Element root = doc.getRootElement();
        List list = root.getChildren("bean");
        for (int i = 0; i < list.size(); i++) {
            Element element = (Element) list.get(i);
            String id = element.getAttributeValue("id");
            String clazz = element.getAttributeValue("class");
            Object o = Class.forName(clazz).newInstance();
            System.out.println(id);
            System.out.println(clazz);
            beans.put(id, o);

            for (Element propertyElement : (List<Element>) element
                    .getChildren("property")) {
                String name = propertyElement.getAttributeValue("name"); // userDAO
                String bean = propertyElement.getAttributeValue("bean"); // u
                Object beanObject = beans.get(bean);// UserDAOImpl instance

                String methodName = "set" + name.substring(0, 1).toUpperCase()
                        + name.substring(1);
                System.out.println("method name = " + methodName);

                Method m = o.getClass().getMethod(methodName,
                        beanObject.getClass().getInterfaces()[0]);
                m.invoke(o, beanObject);
            }

        }

    }

    public Object getBean(String id) {
        return beans.get(id);
    }

}
View Code

beans.xml

技术分享
<beans>
    <bean id="u" class="com.ctsh.dao.impl.UserDAOImpl">

    </bean>
    <bean id="userService" class="com.ctsh.service.UserService">
        <property name="userDAO" bean="u" />
    </bean>

</beans>
beans

LogInterceptor.java

技术分享
package com.ctsh.aop;

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

public class LogInterceptor 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() + " start");
    }

    public Object invoke(Object proxy, Method m, Object[] args)
            throws Throwable {
        beforeMethod(m);
        m.invoke(target, args);
        return null;
    }
}
LogInterceptor

测试类UserServiceTest.java

技术分享
package com.ctsh.service;
import java.lang.reflect.Proxy;

import org.junit.Test;

import com.ctsh.aop.LogInterceptor;
import com.ctsh.dao.UserDAO;
import com.ctsh.dao.impl.UserDAOImpl;
import com.ctsh.model.User;
import com.ctsh.service.UserService;
import com.ctsh.spring.BeanFactory;
import com.ctsh.spring.ClassPathXmlApplicationContext;


public class UserServiceTest {

    @Test
    public void testAdd() throws Exception {
        BeanFactory applicationContext = new ClassPathXmlApplicationContext();
        UserService service = (UserService)applicationContext.getBean("userService");
        User u = new User();
        u.setUsername("zhangsan");
        u.setPassword("zhangsan");
        service.add(u);
    }
    
    @Test
    public void testProxy() {
        UserDAO userDAO = new UserDAOImpl();
        LogInterceptor li = new LogInterceptor();
        li.setTarget(userDAO);
        UserDAO userDAOProxy = (UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(), userDAO.getClass().getInterfaces(), li);
        System.out.println(userDAOProxy.getClass());
        userDAOProxy.delete();
        userDAOProxy.save(new User());
        
    }
}
UserServiceTest

由运行结果可知,在调用对象userDAOProxy的delete()方法和save()方法的时候均输出了日志。

由代码可知,AOP的实现也主要是通过java的代理反射机制实现的,不过值得一提的是,Spring中代理的实现方式还可以通过CGLIB实现。

[Spring系列02]Spring AOP模拟

标签:

原文地址:http://www.cnblogs.com/molyeo/p/4311738.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!