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");// 比较beanIdString 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());}
}