-
什么是springIOC?
就是把每一个bean与bean的关系交给第三方容器sprig管理。spring 的实现就是反射技术与dom4j解析xml 实现的。
-
什么是SpringIOC底层实现原理?
1.读取bean的XML配置文件
2.使用beanId查找bean配置,并获取配置文件中class地址。
3.使用Java反射技术实例化对象
4.获取属性配置,使用反射技术进行赋值。
-
根据以上步骤自己实现一个,以数据库为例
<!-- 数据库配置 -->
18 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
20 <property name="driverClass" value="com.mysql.jdbc.Driver" />
21 <!-- 测试数据库 -->
22 <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3066/TESTDB?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true" />
23 <property name="username" value="root" />
24 <property name="password" value="root" />
43 <property name="maxActive" value="3" />
44 </bean>
实例代码如下:
import com.alibaba.druid.pool.DruidDataSource;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author ngLee
* @version 1.0
* @Desc
* @date 2020/12/2 21:01
*/
public class TestMain {
//外部传入一个xml路径
private static String xmlPath = "applicationContext.xml";
public static void main(String[] args) {
try {
//读取xml 文件,dom4j
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(TestMain.class.getClassLoader().getResource(xmlPath));
//查找bean配置,并获取配置文件中class地址
Element root = document.getRootElement();
List<BeanCfg> ls = (List<BeanCfg>) root.elements().stream().filter(ele -> {
Element em = (Element) ele;
return "bean".equals(em.getName());
}).map(e ->{
Element em = (Element) e;
//设置bean
BeanCfg bean = new BeanCfg();
bean.setId(em.attribute("id").getValue());
bean.setClazz(em.attribute("class").getValue());
//设置属性
List<Element> elep = em.elements("property");
List<BeanCfg.BeanProperties> beanProperties = elep.stream().map(eleo -> {
BeanCfg.BeanProperties pro = bean.new BeanProperties();
pro.setName(eleo.attribute("name").getValue());
pro.setValue(eleo.attribute("value").getValue());
return pro;
}).collect(Collectors.toList());
bean.setProperties(beanProperties);
return bean;
}).collect(Collectors.toList());
//使用Java反射技术实例化对象
for (BeanCfg bean: ls) {
Class clazz = Class.forName(bean.getClazz());
Object object = clazz.newInstance();
//属性
List<BeanCfg.BeanProperties> bps = bean.getProperties();
for (BeanCfg.BeanProperties bpps: bps) {
String namm = bpps.getName();
String value = bpps.getValue();
Method[] methods = clazz.getMethods();
for(Method method : methods){
String methName = method.getName();
//去掉set之后一致
if(methName.startsWith("set") && methName.equalsIgnoreCase("set"+namm)){
//调用方法赋值
method.invoke(object,value);
}
}
}
DruidDataSource dataSource = (DruidDataSource) object;
System.out.println("url-"+dataSource.getUrl()+"--");
System.out.println("username-"+dataSource.getUsername()+"--");
System.out.println("password-"+dataSource.getPassword()+"--");
System.out.println("driverClassName"+dataSource.getDriverClassName()+"--");
}
}catch (Exception e){
e.printStackTrace();
}
}
}
//Benas 类
public class BeanCfg {
//id
private String id;
//packName包名
private String clazz;
private List<BeanProperties> properties;
public List<BeanProperties> getProperties() {
return properties;
}
public void setProperties(List<BeanProperties> properties) {
this.properties = properties;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
//属性
class BeanProperties{
//字段名
private String name;
//值
private String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
-
获取到实例对象之后,下一步交给spring管理。