pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>comgroupId>
<artifactId>springartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>5.2.1.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>5.2.1.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.1.RELEASEversion>
dependency>
dependencies>
project>
UserBean.java
package com.spring.bean;
/**
* @author honey
* @date 2023-08-08 14:58:16
*/
public class UserBean {
}
spring.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userBean" class="com.spring.bean.UserBean"/>
beans>
SpringTest01.java
package com.spring.test;
import com.spring.bean.UserBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author honey
* @date 2023-08-08 14:59:56
*/
public class SpringTest01 {
public static void main(String[] args) {
// 读取spring.xml
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
// 从IOC容器中读取对象
UserBean userBean = applicationContext.getBean("userBean", UserBean.class);
System.out.println(userBean);
}
}
ScanBean.java
package com.spring.bean.scan;
import org.springframework.stereotype.Component;
/**
* @author honey
* @date 2023-08-08 16:37:26
*/
@Component
public class ScanBean {
}
SpringConfig.java
package com.spring.config;
import com.spring.bean.UserBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @author honey
* @date 2023-08-08 16:30:21
*/
@Configuration
@ComponentScan(value = {"com.spring.bean.scan"})
public class SpringConfig {
@Bean(name = "user")
public UserBean userBean() {
return new UserBean();
}
}
SpringTest02.java
package com.spring.test;
import com.spring.bean.UserBean;
import com.spring.bean.scan.ScanBean;
import com.spring.config.SpringConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author honey
* @date 2023-08-08 16:31:25
*/
public class SpringTest02 {
public static void main(String[] args) {
// 加载SpringConfig
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
// 从IOC容器中读取对象
UserBean userBean = applicationContext.getBean("user", UserBean.class);
System.out.println(userBean);
ScanBean scanBean = applicationContext.getBean("scanBean", ScanBean.class);
System.out.println(scanBean);
}
}
底层使用map集合管理对象,key=beanId,value=实例对象
private final Map<String, Object> beanMap = new ConcurrentHashMap<>();
基于反射+工厂模式+DOM技术
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>comgroupId>
<artifactId>ext-spring-iocartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
<version>5.2.1.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
<version>5.2.1.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.1.RELEASEversion>
dependency>
<dependency>
<groupId>dom4jgroupId>
<artifactId>dom4jartifactId>
<version>1.6.1version>
dependency>
dependencies>
project>
UserBean.java
package com.spring.bean;
/**
* @author honey
* @date 2023-08-08 16:56:32
*/
public class UserBean {
}
spring.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userBean" class="com.spring.bean.UserBean"/>
beans>
SpringIocXml.java
package com.spring.ext;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.core.io.ClassPathResource;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author honey
* @date 2023-08-08 16:57:17
*/
public class SpringIocXml {
private final Map<String, Object> beanMap = new ConcurrentHashMap<>();
public SpringIocXml() throws IOException, DocumentException {
init();
}
public <T> T getBean(String name) {
return (T) beanMap.get(name);
}
/**
* 初始化IOC容器
*/
private void init() throws IOException, DocumentException {
// 解析spring.xml配置
ClassPathResource classPathResource = new ClassPathResource("spring.xml");
File xmlFile = classPathResource.getFile();
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(xmlFile);
// 获取根节点
Element rootElement = doc.getRootElement();
// 获取bean节点信息
List<Element> beans = rootElement.elements("bean");
for (Element bean : beans) {
try {
String beanId = bean.attribute("id").getValue();
String classPath = bean.attribute("class").getValue();
// 使用反射机制初始化对象,并将对象存入Map集合
Class<?> clazz = Class.forName(classPath);
Object object = clazz.newInstance();
beanMap.put(beanId, object);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
SpringTest01.java
package com.spring.test;
import com.spring.bean.UserBean;
import com.spring.ext.SpringIocXml;
import org.dom4j.DocumentException;
import java.io.IOException;
/**
* @author honey
* @date 2023-08-08 17:04:35
*/
public class SpringTest01 {
public static void main(String[] args) throws DocumentException, IOException {
SpringIocXml springIocXml = new SpringIocXml();
UserBean userBean = springIocXml.getBean("userBean");
System.out.println(userBean);
}
}
基于反射+工厂模式实现
pom.xml
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
<version>5.7.7version>
dependency>
ScanBean.java
package com.spring.bean.scan;
import org.springframework.stereotype.Component;
/**
* @author honey
* @date 2023-08-09 14:28:33
*/
@Component
public class ScanBean {
}
SpringConfig.java
package com.spring.config;
import com.spring.bean.UserBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @author honey
* @date 2023-08-09 14:26:40
*/
@Configuration
@ComponentScan(value = {"com.spring.bean.scan"})
public class SpringConfig {
@Bean
public UserBean userBean() {
return new UserBean();
}
}
SpringIocAnnotation.java
package com.spring.ext;
import cn.hutool.core.lang.ClassScanner;
import cn.hutool.core.util.StrUtil;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author honey
* @date 2023-08-09 14:12:21
*/
public class SpringIocAnnotation {
private final Object config;
private final Map<String, Object> beanMap = new ConcurrentHashMap<>();
public SpringIocAnnotation(Object config) {
this.config = config;
init();
}
/**
* 初始化IOC容器
*/
public void init() {
// 判断配置类上是否有@Configuration注解
Configuration configuration = this.config.getClass().getDeclaredAnnotation(Configuration.class);
if (configuration == null) {
return;
}
// 处理@Bean注解
Class<?> clazz = config.getClass();
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method method : declaredMethods) {
// 判断方法上是否有@Bean注解
Bean bean = method.getDeclaredAnnotation(Bean.class);
if (bean != null) {
try {
// 获取beanId
String[] value = bean.value();
String beanId = value.length > 0 ? value[0] : method.getName();
// 获取方法的返回值
Object object = method.invoke(config);
beanMap.put(beanId, object);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 处理@Component注解
ComponentScan componentScan = clazz.getDeclaredAnnotation(ComponentScan.class);
if (componentScan != null) {
for (String packageName : componentScan.value()) {
try {
// 扫描指定包下的所有类
Set<Class<?>> classes = ClassScanner.scanPackage(packageName);
for (Class<?> c : classes) {
// 判断类上是否有@Component注解
Annotation component = c.getDeclaredAnnotation(Component.class);
if (component != null) {
try {
// 获取beanId
String beanId = StrUtil.lowerFirst(c.getSimpleName());
// 通过反射技术初始化对象
Object beanObject = c.newInstance();
beanMap.put(beanId, beanObject);
} catch (Exception e) {
e.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public <T> T getBean(String name) {
return (T) beanMap.get(name);
}
}
SpringTest02.java
package com.spring.test;
import com.spring.bean.UserBean;
import com.spring.bean.scan.ScanBean;
import com.spring.config.SpringConfig;
import com.spring.ext.SpringIocAnnotation;
/**
* @author honey
* @date 2023-08-09 14:24:36
*/
public class SpringTest02 {
public static void main(String[] args) {
SpringIocAnnotation springIocAnnotation = new SpringIocAnnotation(new SpringConfig());
UserBean userBean = springIocAnnotation.getBean("userBean");
System.out.println(userBean);
ScanBean scanBean = springIocAnnotation.getBean("scanBean");
System.out.println(scanBean);
}
}