目录
Spring简介
Spring是模块化的,意味着可以只使用需要的Spring模块。Spring模块主要分为以下模块:
- 核心容器(core container)。Spring-core是核心工具类,Spring其他模块大量使用Spring-core; Spring-Beans Spring定义Bean的支持; Spring-Content为运行时Spring容器;Spring-context-Support为Spring容器对第三方包的集成支持;Spring-Expression为使用表达式语言在运行时查询和操作的对象。
- AOP(Aspect oriented programming)。Spring-AOP 基于代理的AOP支持;Spring-Aspects 基于AspectJ的AOP支持
- 消息。Spring-Messaging 对消息架构和协议的支持。
- web。Spring-Web 提供基础的Web集成功能,在web项目中提供Spring的容器;Spring-Webmvc 提供基于Servlet的Spring MVC;Spring-WebSocket 提供WebSocket功能;Spring-Webmvc-Portlet 提供Portlet环境支持。
- 数据访问/集成。Spring-JDBC 提供已JDBC访问数据库的支持;Spring-TX 提供对对象/关系映射技术的支持;Spring-OXM 提供对对象/xml映射技术的支持;Spring-JMS 提供对JMS的支持。
Spring的生态
IOC(依赖注入), 依赖注入指的是容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖。Spring Ioc容器(ApplicationContext)负责创建Bean,并通过容器将功能类Bean注入到需要的Bean中。Spring提供使用xml、注解、Java配置、groovy配置实现Bean的创建和注入。
java配置实例
下面是使用java类进行依赖注入,实现对象的管理。
package com.packaget.spring.ch1.javaconfig;
// 编写功能bean
public class FunctionService {
public String sayHello(String word)
{
return "Hello " + word + " !";
}
}
package com.packaget.spring.ch1.javaconfig;
// 使用bean
public class UseFunctionService {
FunctionService functionService;
public void setFunctionService(FunctionService functionService)
{
this.functionService = functionService;
}
public String SayHello(String word)
{
return functionService.sayHello(word);
}
}
package com.packaget.spring.ch1.javaconfig;
// 配置类
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JavaConfig {
@Bean
public FunctionService functionService(){
return new FunctionService();
}
@Bean
public UseFunctionService useFunctionService(){
UseFunctionService useFunctionService = new UseFunctionService();
useFunctionService.setFunctionService(functionService());
return useFunctionService;
}
}
package com.packaget.spring.ch1.javaconfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);
UseFunctionService useFunctionService = context.getBean(UseFunctionService.class);
System.out.println(useFunctionService.SayHello("java config"));
context.close();
}
}
IOC实现原理
下面简要的分析一下IOC的实现思路,并通过一个实例来模拟实例IOC容器实例化。思路如下
- 实例化Bean工厂接口,提供获取Bean的方法
- 定义Bean工厂接口实现类,解析配置文件,实例化Bean对象
- 实现获取Bean对象
package com.packaget.spring.factory;
// 工厂接口
public interface MyFactory {
Object getBean(String id);
}
package com.packaget.spring.service;
public class MyBean {
private String Id; // 保存id
private String clazz; // 保存类路径
public MyBean(String id, String clazz) {
Id = id;
this.clazz = clazz;
}
public String getId() {
return Id;
}
public void setId(String id) {
Id = id;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
}
package com.packaget.spring.dao;
public class UserDao {
public void test()
{
System.out.println("userDao...");
}
}
package com.packaget.spring.service;
public class UserService {
public void test(){
System.out.println("userService ...");
}
}
<?xml version="1.0" encoding="utf-8" ?>
<!-- 配置文档 -->
<beans>
<bean id="userService" class="com.packaget.spring.service.UserService"/>
<bean id="userDao" class="com.packaget.spring.dao.UserDao"/>
</beans>
package com.packaget.spring.factory;
import com.packaget.spring.service.MyBean;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.XPath;
import org.dom4j.io.SAXReader;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MypathXmlContent implements MyFactory {
private Map<String, Object> map = new HashMap<>();
private List<MyBean> elist = null;
public MypathXmlContent(String fileName)
{
this.parseXml(fileName); // 解析xml配置文档
this.initBeans(); // 实例化对象并放入容器
}
private void parseXml(String fileName) {
URL url = this.getClass().getClassLoader().getResource(fileName); // 获取文件地址
SAXReader reader = new SAXReader(); // xml读取器
try {
Document document = reader.read(url); // 读取xml内容
XPath xPath = document.createXPath("beans/bean"); // 筛选节点
List<Element> elementList = xPath.selectNodes(document); // 将节点保存到list中
if (elementList != null && elementList.size() > 0) // 保存每个bean
{
elist = new ArrayList<>();
for(Element e : elementList) {
String id = e.attributeValue("id");
String clazz = e.attributeValue("class");
System.out.println(id);
System.out.println(clazz);
elist.add(new MyBean(id, clazz));
}
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
private void initBeans() { // 实例化list中的bean,并保存在map中
if(elist != null && elist.size() > 0)
{
for(MyBean bean : elist)
{
try {
map.put(bean.getId(), Class.forName(bean.getClazz()).getDeclaredConstructor().newInstance()); // 利用反射实例化
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
@Override
public Object getBean(String id) { // 接口方法
return map.get(id);
}
}
结果