您的位置:首页 > 编程语言 > Java开发

Spring 实现IOC容器(二)

2016-05-30 21:41 465 查看
连载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()-----
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring ioc