Spring
-
IoC(控制反转)/ DI(依赖注入)
-
AOP(面向切面编程)
Spring 是一个企业级开发框架,是软件设计层面的框架,优势在于可以将应用程序进行分层,开发者可以自主选择组件。
MVC:Struts2、Spring MVC
如何使用 IoC
-
创建 Maven 工程,pom.xml 添加依赖
-
创建实体类 Student
package com.kalfin.entity;
import lombok.Data;
-
传统的开发方式,手动 new Student
Student student = new Student();
student.setId(1L);
student.setName("张三");
student.setAge(22);
System.out.println(student);
-
通过 IoC 创建对象,在配置文件中添加需要管理的对象,XML 格式的配置文件,文件名可以自定义。
-
从 IoC 中获取对象,通过 id 获取。
//加载配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
Student student = (Student) applicationContext.getBean("student");
System.out.println(student);
配置文件
-
通过配置
bean
标签来完成对象的管理。-
id
:对象名。 -
class
:对象的模版类(所有交给 IoC 容器来管理的类必须有无参构造函数,因为 Spring 底层是通过反射机制来创建对象,调用的是无参构造)
-
-
对象的成员变量通过
property
标签完成赋值。-
name
:成员变量名。 -
value
:成员变量值(基本数据类型,String 可以直接赋值,如果是其他引用类型,不能通过 value 赋值) -
ref
:将 IoC 中的另外一个 bean 赋给当前的成员变量(DI)
<bean id="student" class="com.kalfin.entity.Student">
<property name="id" value="1"></property>
<property name="name" value="张三"></property>
<property name="age" value="22"></property>
<property name="address" ref="address"></property>
</bean>
<bean id="address" class="com.kalfin.entity.Address">
<property name="id" value="1"></property>
<property name="name" value="科技路"></property>
</bean> -
IoC 底层原理
-
读取配置文件,解析 XML。
-
通过反射机制实例化配置文件中所配置所有的 bean。
package com.kalfin.ioc;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class ClassPathXmlApplicationContext implements ApplicationContext {
private Map<String,Object> ioc = new HashMap<String, Object>();
public ClassPathXmlApplicationContext(String path){
try {
SAXReader reader = new SAXReader();
Document document = reader.read("./src/main/resources/"+path);
Element root = document.getRootElement();
Iterator<Element> iterator = root.elementIterator();
while(iterator.hasNext()){
Element element = iterator.next();
String id = element.attributeValue("id");
String className = element.attributeValue("class");
//通过反射机制创建对象
Class clazz = Class.forName(className);
//获取无参构造函数,创建目标对象
Constructor constructor = clazz.getConstructor();
Object object = constructor.newInstance();
//给目标对象赋值
Iterator<Element> beanIter = element.elementIterator();
while(beanIter.hasNext()){
Element property = beanIter.next();
String name = property.attributeValue("name");
String valueStr = property.attributeValue("value");
String ref = property.attributeValue("ref");
if(ref == null){
String methodName = "set"+name.substring(0,1).toUpperCase()+name.substring(1);
Field field = clazz.getDeclaredField(name);