Spring它是容器, 类的实例bean Spring容
器管理,Spring的核心是 IOC/DI/AOP
IOC是控制反转:
加载指定xml,利用反射机制进行对象的实例化
DI依赖注入对象:
<bean id="tag1" class="com.example.demo.entity.Tag">
<property name="tagCode" value="0001"></property>
<property name="name" value="张三"></property>
</bean>
<!-- setter方式赋值 -->
<bean id="tag2" class="com.example.demo.entity.Tag">
<property name="tagCode" value="0002"></property>
<property name="name" value="李四"></property>
</bean>
<!-- 构造函数方式赋值 -->
<bean id="tag3" class="com.example.demo.entity.Tag">
<constructor-arg name="tagCode" value="123"></constructor-arg>
<constructor-arg name="name" value="IOC创建方式:通过构造函数创建"></constructor-arg>
</bean>
<!-- 创建工厂 -->
<bean id="factory" class="com.example.demo.learn.factory.ObjectFactory">
</bean>
<!-- 通过工厂进行创建bean -->
<bean id="tag4" factory-bean="factory" factory-method="getTagEntity">
</bean>
<!-- 通过静态工厂创建bean -->
<bean id="tag5" class="com.example.demo.learn.factory.ObjectFactory" factory-method="getStaticTagEntity">
</bean>
public class RetentionTest {
private static String path = "classpath:config/applicationContext.xml";
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(path);
Tag tag = (Tag) context.getBean("tag1");
Tag tag1 = (Tag) context.getBean("tag1");
// 两个对象是相等的,表明Spring默认是单例的,线程安全问题
System.out.println(tag == tag1);
System.out.println(tag.getTagCode() + " >> " + tag.getName());
// 通过构造函数实例化对象
Tag tag3 = (Tag) context.getBean("tag3");
System.out.println(tag3.getTagCode() + " >> " + tag3.getName());
// 通过工厂实例化对象
Tag tag4 = (Tag) context.getBean("tag4");
System.out.println(tag4.getTagCode() + " >> " + tag4.getName());
// 通过静态工厂
Tag tag5 = (Tag) context.getBean("tag5");
System.out.println(tag5.getTagCode() + " >> " + tag5.getName());
}
}
package com.example.demo.learn.factory;
import com.example.demo.entity.Tag;
public class ObjectFactory {
public Tag getUserEntity() {
System.out.println("通过静态工厂方式创建对象");
return new Tag("1230","工厂方式创建对象");
}
}
Spring中的 beanId 如果重复了,会有怎么效果?
xml的bean id 不允许设置唯一的,如果相同会报错
package com.example.demo.learn.retention;
import com.example.demo.entity.Tag;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.lang.reflect.Field;
import java.util.List;
public class ClassPathContext {
private String xmlPath;
public ClassPathContext(String path) {
this.xmlPath = path;
}
/**
* SpringIOC实现原理
*/
public Object getBean(String id) throws DocumentException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
Object obj = null;
SAXReader saxReader = new SAXReader();
// 读取xml配置文件
Document read = saxReader.read(this.getClass().getClassLoader().getResourceAsStream(xmlPath));
// 获取根节点
Element rootElement = read.getRootElement();
List<Element> elements = rootElement.elements();
for (Element element : elements) {
// 获取类的地址
String beanClassPath = element.attributeValue("class");
// 比较beanId
String beanId = element.attributeValue("id");
if (!beanId.equals(id)) {
continue;
}
// 获取class,反射实例化对象
Class<?> beanClass = Class.forName(beanClassPath);
obj = beanClass.newInstance();
// 子元素
List<Element> eleList = element.elements();
for (Element ele : eleList) {
String name = ele.attributeValue("name");
String value = ele.attributeValue("value");
// 使用反射api为私有属性赋值
Field field = beanClass.getDeclaredField(name);
field.setAccessible(true);
field.set(obj,value);
}
}
return obj;
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, DocumentException, NoSuchFieldException {
ClassPathContext context = new ClassPathContext("config/applicationContext.xml");
Tag tag1 = (Tag) context.getBean("tag1");
System.out.println(tag1.getTagCode() + " >> " + tag1.getName());
}
}