1.常规的类管理方式是:1.使用动态代理将业务逻辑的实现类构建出来,Dao jdkProxy= (Dao) Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{Dao.class}, new NiuInvocationHandler(new DaoImpl()));
然后执行相应的业务逻辑。
2.将把类放入工厂中,让工厂进行处理。
使用dom4j 获取XML文件
官网:https://dom4j.github.io/
1.获取document:
public class Foo {
public Document parse(URL url) throws DocumentException {
//SAXReader 是Dom4j提供用于读取XML的操作类
SAXReader reader = new SAXReader();
//Document存储了读取进来的XML文档的内容
Document document = reader.read(url);
return document;
}
}
document:{A document can be navigated using a variety of methods that return standard Java Iterators}document能够使用不同的方法来返回标准的java迭代器去导航需要的地方(或者节点)
Element root = document.getRootElement();
// iterate through child elements of root
for (Iterator<Element> it = root.elementIterator(); it.hasNext();) {
Element element = it.next();
// do something
}
根据Element获取Attribute
Attribute attributeId= element.attribute("id");
String beanName= attributeId.getValue();
模拟一个简单Spring
先模拟一个工具类
package com.org.spring.util;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class BeanFactory {
Map map=new HashMap<String,Object>();
//解析XML技术
public BeanFactory(String Xml) {
parseXml(Xml);
}
//用于读取XML文件
public void parseXml(String xml)throws NiuSpringException{
File file=new File(this.getClass().getResource("/").getPath()+"//"+xml);
SAXReader reader = new SAXReader();
try {
Document document = reader.read(file);
Element elementRoot= document.getRootElement();
List<Element> allChild=elementRoot.elements();
Attribute attribute= elementRoot.attribute("default");
boolean flag=false;
if (attribute!=null){
flag=true;
}
for (Iterator<Element> itFirst = elementRoot.elementIterator(); itFirst.hasNext();) {
//实例化对象
Element elementFirstChiled = itFirst.next();
//获取配置文件中bean中id的名称
Attribute attributeId= elementFirstChiled.attribute("id");
String beanName= attributeId.getValue();
//获取配置文件中bean中具体的实现类
Attribute attributeClass= elementFirstChiled.attribute("class");
String calzzName= attributeClass.getValue();
Class clazz=Class.forName(calzzName);
//1.使用的Set方法进行注入的
// 获取当前bean中有没有property属性,也就是获取第二层的内容
Object object=null;
for (Iterator<Element> itSecond = elementFirstChiled.elementIterator(); itSecond.hasNext();) {
/**
* 通过ref获得Value,得到它依赖对象的Bean的名称。
* 根据Value的值获取一个Failed对象。
* 通过Failed的set的方法,去set那个对象
* */
Element elementSecondChild=itSecond.next();
if (elementSecondChild.getName().equals("property")) {
System.out.println("走了吗手动");
object =clazz.newInstance();
//获取ref对应的bean,并得到相应的对象,
// 用于对当前类的相应的属性进行赋值。
String refValue=elementSecondChild.attribute("ref").getValue();
Object injetObject= map.get(refValue);
//获取name中的属性名称也就是和当前类的set方法的名字一致
String nameValue=elementSecondChild.attribute("name").getValue();
Field field=clazz.getDeclaredField(nameValue);
//获取对应的set方法
field.setAccessible(true);
//field.set在指定的的对象上对当前属性进行赋值
// 第一个参数是当前对象的值,第二个参数是进行set赋值的类
field.set(object,injetObject);
}
//有构造方法时
else {
String refValue=elementSecondChild.attribute("ref").getValue();
Object injetObject= map.get(refValue);
Class injectObjectClazz=injetObject.getClass();
//获取构造方法
Constructor constructor= clazz.getConstructor(injectObjectClazz.getInterfaces()[0]);
object= constructor.newInstance(injetObject);
}
}
//如果bean中有property,也就是手动装配了,则就不需要进行自动装配了
//因为object在手动装配的时候会赋值,所以可以根据其是否为空进行判定
if (object ==null) {
System.out.println("走了吗");
if (flag) {
if (attribute.getValue().equals("byType")) {
//判断是否依赖,也就是获取当前类是否有属性
Field fields[] = clazz.getDeclaredFields();
for (Field field : fields) {
//获得属性的类型
Class injectObjectClazz = field.getType();
/**
* 由于是byType,所有需要遍历map当中所有的对象
* 找出和injectObjectClazz类型相同的对象
* */
int count = 0;
Object injectObject = null;
for (Object key : map.keySet()) {
//获取当前类中的接口,
Class temp = map.get(key).getClass().getInterfaces()[0];
//判断属性接口的名称和从Map中获得的名称一致
if (temp.getName().equals(injectObjectClazz.getName())) {
injectObject = map.get(key);
//记录来找到一个,因为可能找到多个
count++;
}
}
if (count > 1) {
throw new NiuSpringException("需要一个对象但是找到了两个对象");
} else {
//现将当前对象New出来,然后把属性值拿出来
object = clazz.newInstance();
field.setAccessible(true);
field.set(object, injectObject);
}
}
}
}
}
//初始化未被创建的对象,例如被依赖的对象
if (object==null){
object=clazz.newInstance();
}
map.put(beanName,object);
}
//System.out.println(map);
} catch (Exception e) {
e.printStackTrace();
}
}
//生成需要的对象
public Object getBean(String beanName){
return map.get(beanName);
}
}
配置文件代码
<?xml version="1.0" encoding="UTF-8"?>
<!--
1.那些类需要管理
2.怎么告诉我 (写Bean标签)
3.怎么维护他们的关系 setter construct
4.怎么体现 setter或者 construct
-->
<beans default="byType">
<bean id="dao" class="com.niu.dao.UserDaoImpl"></bean>
<!--<bean id="dao1" class="com.niu.dao.UserDaoImpl1"></bean>-->
<bean id="service" class="com.niu.service.UserServiceImpl">
<!--setter方法-->
<!-- <property name="dao1" ref="dao1"></property>-->
<!-- <constructor-arg name="dao" ref="dao"></constructor-arg>-->
</bean>
</beans>
定义一个异常类
public class NiuSpringException extends RuntimeException {
public NiuSpringException(String msg){
super(msg);
}
}
public interface UserDao {
public void query();
}
public class UserDaoImpl implements UserDao {
public void query() {
System.out.println("dao");
}
}
public class UserServiceImpl implements UserSivice {
UserDao dao1;
/*public UserServiceImpl(UserDao dao) {
this.dao = dao;
}*/
public void find() {
System.out.println("service");
dao1.query();
}
/* public void setDao(UserDao dao) {
this.dao = dao;
}*/
}
public interface UserSivice {
public void find();
}
public class Test {
public static void main(String[] args) {
BeanFactory beanFactory=new BeanFactory("spring.xml");
//通过beanFactory获取相应的Bean
UserSivice userSivice= (UserSivice) beanFactory.getBean("service");
userSivice.find();
}
}