Spring IoC 简单案例
Posted GoldenaArcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring IoC 简单案例相关的知识,希望对你有一定的参考价值。
Spring IoC 简单案例
IoC(Inversion of Control)是一种设计模式,维基百科的说法是这样的:
Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式地用 new 建立 B 的对象。
采用依赖注入技术之后,A 的代码只需要定义一个 private 的B对象,不需要直接 new 来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中。而具体获取的方法、对象被获取时的状态由配置文件(如XML)来指定。
IoC也可以理解为把流程的控制从应用程序转移到框架之中。以前,应用程序掌握整个处理流程;现在,控制权转移到了框架,框架利用一个引擎驱动整个流程的执行,框架会以相应的形式提供一系列的扩展点,应用程序则通过定义扩展的方式实现对流程某个环节的定制,“框架Call应用”。基于MVC的web应用程序就是如此。
简单的说就是,提供一个 callback ——any kind of callback (which controls reaction)
而非直接由开发直接控制管理 ——in other words, inversion and/or redirecting control to external handler/controller
。
参考案例如下:
创建一个教练管理软件,这个教练管理软件需要满足两个需求:
- 可配置
- 可以更换为其他运动教练
使用非 IoC 的实现如下:
package springdemo;
public interface Coach
public String getDailyWorkout();
package springdemo;
public class TrackCoach implements Coach
@Override
public String getDailyWorkout()
return "Run a hrad 5k.";
package springdemo;
public class BaseballCoach implements Coach
@Override
public String getDailyWorkout()
return "Spend 30 minutes on batting practice.";
package springdemo;
public class MyApp
public static void main(String[] args)
// create the object
Coach theCoach = new TrackCoach();
// Coach theCoach = new BaseballCoach();
// use the object
System.out.println(theCoach.getDailyWorkout());
流程图为;
这个实现方法中,要想要新建一个任意教练的实例都必须要在代码中进行修改,这样就无法满足一个可配置的需求。但是,这个时候可以借助 Spring IoC 来完成这一需求。
Spring 中有三种方式可以实现 IoC:
- XML 配置(旧)
- Java 注解(新)
- Java 代码(新)
这里会通过 XML 来完成配置。
开发过程如下:
- 配置 spring beans
- 创建 sprint container
- 通过 container 获取 beans
一个 “Spring Bean” 简单来说就是一个 Java 对象,官方文档中写着:
In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.
XML 配置 Spring Bean
XML 文件有自己的格式,主体部分如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Define your beans here -->
<!-- id is like an alias -->
<bean id="myCoach" class="springdemo.TrackCoach"></bean>
</beans>
这里主要的部分就是这一行:<bean id="myCoach" class="springdemo.TrackCoach"></bean>
,这一行就创建了一个新的 Spring Bean,指向的类为 TrackCoach
,之后也可以修改为 TrackCoach
或是其他,但是无论如何都不需要修改 Java 源码。
这时候创建一个新的主函数导入 XML 文件:
package springdemo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloSpringApp
public static void main(String[] args)
// load the spring configuration file
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
// retrieve bean from spring container
// 2nd arg is the interface
Coach theCoach = context.getBean("myCoach", Coach.class);
// call methods on the bean
System.out.println(theCoach.getDailyWorkout());
// close the context
context.close();
这样在修改教练的时候不需要修改源码,只需要修改配置文件 applicationContext.xml
即可。
额外的 logging
Spring 5.1 默认移除了一部分的 Logging,这里的配置会把一些 logging 加回来:
新的 Logging java:
package springdemo;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyLoggerConfig
private String rootLoggerLevel;
private String printedLoggerLevel;
public void setRootLoggerLevel(String rootLoggerLevel)
this.rootLoggerLevel = rootLoggerLevel;
public void setPrintedLoggerLevel(String printedLoggerLevel)
this.printedLoggerLevel = printedLoggerLevel;
public void initLogger()
// parse levels
Level rootLevel = Level.parse(rootLoggerLevel);
Level printedLevel = Level.parse(printedLoggerLevel);
// get logger for app context
Logger applicationContextLogger = Logger.getLogger(AnnotationConfigApplicationContext.class.getName());
// get parent logger
Logger loggerParent = applicationContextLogger.getParent();
// set root logging level
loggerParent.setLevel(rootLevel);
// set up console handler
ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(printedLevel);
consoleHandler.setFormatter(new SimpleFormatter());
// add handler to the logger
loggerParent.addHandler(consoleHandler);
XML 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Define your beans here -->
<!-- id is like an alias -->
<bean id="myCoach" class="springdemo.TrackCoach"></bean>
<bean id="myLoggerConfig" class="springdemo.MyLoggerConfig" init-method="initLogger">
<property name="rootLoggerLevel" value="FINE" />
<property name="printedLoggerLevel" value="FINE"/>
</bean>
</beans>
Reference
以上是关于Spring IoC 简单案例的主要内容,如果未能解决你的问题,请参考以下文章