关闭

Spring 实现IOC容器(二)

标签: springioc
335人阅读 评论(6) 收藏 举报
分类:

连载2,:Spring中实现IOC容器,应用动态代理。

结构目录:


我们同样从上到下写:

ContainTest:


package com.tgb.client;

import com.tgb.config.BeanFactory;
import com.tgb.config.ClassPathXmlApplicationContext;
import com.tgb.dao.UserDao;
import com.tgb.domain.User;
/**
 * 测试容器AOP效果
* @ClassName: ContainTest 
* @Description: 
* @author qmx 
* @date 2016年5月30日 
*
 */
public class ContainTest {

	public static void main(String[] args) throws Exception {

		//初始化容器对象
		BeanFactory factory = new ClassPathXmlApplicationContext();

		User user = new User();
		user.setUserName("hanyankun");

		//获取容器中userDao对象
		UserDao userDao = (UserDao) factory.getBean("UserDao");

		System.out.println("-----测试一");
	
		userDao.save(user);
	}
}

AspectBean:


package com.tgb.config;

/***
 * 
 * 日志对象
 */
public class AspectBean {

	public void before(Object proxy) {

		System.out.println("---Before1-日志----");
	}

	public static void after(Object proxy) {
		System.out.println("---After1-日志---");
	}

	public void save(Object proxy) {
		System.out.println("---Save1-日志--");
	}
}

AspectBean2:


package com.tgb.config;

/**
 * 事务对象
* @ClassName: AspectBean2 
* @Description: TODO(这里用一句话描述这个类的作用) 
* @author 
* @date 
*
 */
public class AspectBean2 {
				
	public  void before(Object proxy) {

		System.out.println("---Before2-事务--");
	}

	public static void after(Object proxy) {
		System.out.println("---After2-事务--");
	}
	public void save(Object proxy){
		System.out.println("---Save2-事务--");
	}
}

BeanFactory:


package com.tgb.config;

import java.util.List;
import java.util.Map;

public interface BeanFactory {
	/**
	 * 获取容器中指定对象
	 * 
	 * @param id
	 *            对象名称如: getBean("user")
	 * @return
	 */
	public Object getBean(String id);

	/**
	 * 容器中放入对象
	 * 
	 * @param k
	 * @param v
	 * @return
	 */
	public Object put(String k, Object v);

	/**
	 * 打印容器中所有对象类型
	 */
	public void printTypeName();

	/**
	 * 获取容器中所有对象 返回类型 Map<string(对象类型),Object(对象)>
	 * 
	 * @return Map<string(对象类型),Object(对象)>
	 */
	public Map<String, Object> getAllBean();
	
	/**
	 * 获取容器所有bean
	 */
	public void printAllbeanId();

	public void remove(String id);

	/**
	 * 容器中对象的数量
	 * @return
	 */
	public int size();
}

ClassPathXmlApplication:


package com.tgb.config;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;

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

/*@ClassName: ContainerBeans 
* @Description: 容器接口,提供容器公共服务方法, 增加,删除,遍历,获取对象,遍历类型,容器大小等方法
* @author 
**/
public class ClassPathXmlApplicationContext implements BeanFactory {

	//对象集合(包含服务类,关系类和业务类)
	private Map<String, Object> beans = new HashMap<String, Object>();

	//是否启用aop
	private boolean isAop = true;

	public ClassPathXmlApplicationContext() throws Exception {
		SAXBuilder sb = new SAXBuilder();

		//读取xml为doc文档
		Document doc = sb.build(Thread.currentThread().getContextClassLoader()
				.getResourceAsStream("beans.xml"));
		Element root = doc.getRootElement();
		Element aopElement = (Element) root.getChildren("aop").get(0);

		//获取aop标签
		isAop = Boolean.parseBoolean(aopElement.getAttributeValue("isaop"));
		//获取bean标签为list
		List list = root.getChildren("bean");
		List aopBeforeList = root.getChildren("aspectbefore");//前置增强
		List aopAfterList = root.getChildren("aspectafter");
		if(aopBeforeList!=null){
			beans.put("aspectbefore", aopBeforeList);
			
		}
		if(aopAfterList!=null){
			beans.put("aspectafter", aopAfterList);
		}
		//读取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();

			beans.put(id, o);

			//for循环判断将依赖项逐项实例化,进行set注入
			for (Element propertyElement : (List<Element>) element
					.getChildren("property")) {
				String name = propertyElement.getAttributeValue("name"); // userDAO
				String bean = propertyElement.getAttributeValue("ref"); // u
				Object beanObject = beans.get(bean);// UserDAOImpl instance
				//获取对象属性,set方法
				String methodName = "set" + name.substring(0, 1).toUpperCase()
						+ name.substring(1);

				//获取具体method方法
				Method m = o.getClass().getMethod(methodName,
						beanObject.getClass().getInterfaces()[0]);
				//调用该方法
				m.invoke(o, beanObject);
			}

		}

	}

	/**
	 * 获取容器中指定对象
	 * 
	 * @param id
	 *            对象名称如: getBean("user")
	 * @return
	 */
	public Object getBean(String id) {

		if (!isAop) {
			return beans.get(id);
		}
		return new JDKDynamicProxy(beans.get(id),beans).getProxy();
	}

	/**
	 * 容器中放入对象
	 * 
	 * @param k
	 * @param v
	 * @return
	 */
	public Object put(String k, Object v) {

		return beans.put(k, v);
	}

	/**
	 * 打印容器中所有对象类型
	 */
	public void printTypeName() {

		Set<String> hashSet = new HashSet<String>();
		Set<Entry<String, Object>> entryset = beans.entrySet();
		{
			Iterator iterator = entryset.iterator();
			while (iterator.hasNext()) {
				Entry<String, Object> entry = (Entry<String, Object>) iterator.next();
				hashSet.add(entry.getValue().getClass().getSimpleName());
			}

		}
		for (String setType : hashSet) {
			System.out.println(setType);
		}

	}

	/**
	 * 获取容器中所有对象
	 * 
	 * @return Map<string(对象类型),Object(对象)>
	 */
	public Map<String, Object> getAllBean() {
		Map<String, Object> beanList = new HashMap<String, Object>();
		Iterator iterator = beans.entrySet().iterator();
		while (iterator.hasNext()) {
			Entry<String, Object> entry = (Entry<String, Object>) iterator.next();
			beanList.put(entry.getValue().getClass().getSimpleName(), entry.getValue());
		}
		return beanList;

	}

	/***
	 * 删除指定对象
	 */
	public void remove(String id) {
		beans.remove(id);

	}

	/***
	 * 打印所有注入对象
	 */
	public void printAllbeanId() {
		Set<Entry<String, Object>> entryset = beans.entrySet();
		
		Set<String> linkSet = new TreeSet<String>();
		{
			Iterator iterator = entryset.iterator();
			while (iterator.hasNext()) {
				Entry<String, Object> entry = (Entry<String, Object>) iterator.next();
				linkSet.add(entry.getKey());
//				System.out.println(entry.getKey());
			}

			System.out.println(linkSet.toString());
			System.out.println("容器中的对象个数是"+size()+"个");
		}
		
			
		
	}

	/**
	 * 获取容器中对象的个数
	 */
	public int size() {
		return beans.size();
	}
}

JDKDynamicProxy:


package com.tgb.config;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;
import java.util.Map;

import org.jdom.Element;

/***
 * ClassName: JDKDynamicProxy 
* @Description: AOP实现对业务容器 的增强,对业务容器中每个对象增强 服务类中的方法,根据 关系容器配置,
* 实现特性方法增强
 * @author qmx
 *
 */
public class JDKDynamicProxy implements InvocationHandler {

	private Object target;//被代理类

	//对象集合(包含服务类,关系类和业务类)
	private Map<String, Object> aspectObject;

	public JDKDynamicProxy(Object target, Map<String, Object> aspectMap) {
		this.target = target;
		this.aspectObject = aspectMap;
	}

	//获取代理对象
	@SuppressWarnings("unchecked")
	public <T> T getProxy() {
		return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target
				.getClass().getInterfaces(), this);
	}

	//回调对象,根据传入对象调用代理类方法
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

		//获取对象关系
		List beforeList = (List) aspectObject.get("aspectbefore");
		//回调服务对象方法
		invokeAspectName(beforeList, method, args);
		//回调代理对象方法
		Object result = method.invoke(target, args);

		return result;
	}

	/**
	 * 拦截方法匹配
	 * 
	 * @param beforeList
	 *            拦截器的所有对象
	 * @param method
	 * @param args
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	public void invokeAspectName(List beforeList, Method method, Object[] args)
			throws NoSuchMethodException, SecurityException, IllegalAccessException,
			IllegalArgumentException, InvocationTargetException {
		if (beforeList != null) {

			for (int i = 0; i < beforeList.size(); i++) {

				Element element = (Element) beforeList.get(i);
				String aspectClass = element.getAttributeValue("ref");// 获取容器中切入类名称
				String aspectName = element.getAttributeValue("aspectMethod");// 执行的切入方法
				Class clazz = aspectObject.get(aspectClass).getClass(); // 获取切入类
				String elementMethod = element.getAttributeValue("method");// 获取被切入类方法
				if (aspectName == null) {

					Method[] methods = clazz.getMethods();
					for (int j = 0; j < methods.length; j++) {

						System.out.println("获取全部公共方法的方法:" + methods[j].toString());

					}

				} else {
					if (method.getName().equals(elementMethod)) {
						Method jinectmethod = clazz.getMethod(aspectName, Object.class); // 反射调用切入类方法
						jinectmethod.invoke(aspectObject.get(aspectClass), args);
					}
				}

			}

		}
	}
}

UserDao:


package com.tgb.dao;

import com.tgb.domain.User;

public interface UserDao {

	void save(User user);	
}

UserDaoImpl:

package com.tgb.daoImpl;

import com.tgb.dao.UserDao;
import com.tgb.domain.User;

public class UserDaoImpl implements UserDao {

	@Override
	public void save(User user) {
	System.out.println( this.getClass()+"-----userDao.save()-----");		
	}
}

User:


package com.tgb.domain;

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;
	}
	
	
}

UserService:


package com.tgb.service;

import com.tgb.dao.UserDao;
import com.tgb.daoImpl.UserDaoImpl;
import com.tgb.domain.User;

public class UserService {

	private UserDao userDao;

	public UserDao getUserDao() {
		return userDao;
	}

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

	public void addUser(User user) {
		userDao.save(user);
		System.out.println("----UserService.add()-----");
	}
}

bean.xml:


<beans>
<!-- 业务对象 -->
	<bean id="UserDao" class="com.tgb.daoImpl.UserDaoImpl" />
	<bean id="userService" class="com.tgb.service.UserService">
		<property name="userDao" ref="UserDao" />
	</bean>	
	
	<!-- 服务类 -->
	<bean id="aspectBean" class="com.tgb.config.AspectBean"></bean>
	<bean id="aspectBean2" class="com.tgb.config.AspectBean2"></bean>
	
	
	<aop isaop="true"></aop>

<!-- 关系配置(业务与服务配置) -->
	<aspectbefore  ref="aspectBean" method="save" aspectMethod="save"></aspectbefore>
	<aspectbefore  ref="aspectBean2" method="before" aspectMethod="after"></aspectbefore>
	<aspectafter ref="aspectBean" method="after" aspectMethod="before"></aspectafter>
</beans>


运行之后的效果为:


-----测试一
---Save1-日志--
class com.tgb.daoImpl.UserDaoImpl-----userDao.save()-----



2
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:295056次
    • 积分:11934
    • 等级:
    • 排名:第1231名
    • 原创:184篇
    • 转载:1篇
    • 译文:0篇
    • 评论:3299条
    博客专栏
    最新评论