Spring IoC,Spring Bean示例教程
欢迎使用Spring IoC示例教程。
Spring框架基于控制反转原则构建。
依赖注入是在应用程序中实现IoC的技术。
SpringIoC
今天,我们将研究Spring IoC容器。
我们还将介绍Spring Bean。
下表是内容列表,可快速导航到Spring IoC教程的不同部分。
- SpringIoC
- Spring Bean
- Spring Bean 范围
- Spring Bean配置
- 基于Spring IoC和Spring Bean ExampleXML的Spring Bean配置
- 基于注释的Spring Bean配置
- 基于Java的Spring Bean配置
SpringIoC容器
Spring IoC是一种实现对象依赖关系之间松散耦合的机制。
为了在运行时实现对象的松散耦合和动态绑定,其他的汇编器对象会注入对象依赖项。
Spring IoC容器是将依赖项注入到对象中并使其可供我们使用的程序。
我们已经研究了如何使用Spring Dependency Injection在我们的应用程序中实现IoC。
Spring IoC容器类是org.springframework.beans和org.springframework.context包的一部分。
Spring IoC容器为我们提供了分离对象依赖关系的不同方法。
BeanFactory是Spring IoC容器的根接口。
ApplicationContext是BeanFactory接口的子接口,提供Spring AOP功能,i18n等。
" ApplicationContext"的一些有用的子接口是" ConfigurableApplicationContext"和" WebApplicationContext"。
Spring框架提供了许多有用的ApplicationContext实现类,我们可以使用它们来获取Spring上下文,然后获取Spring Bean。
我们使用的一些有用的ApplicationContext实现是:
AnnotationConfigApplicationContext:如果我们在独立的Java应用程序中使用Spring并为Configuration使用注释,那么我们可以使用它来初始化容器并获取Bean对象。
ClassPathXmlApplicationContext:如果我们在独立应用程序中具有spring bean配置xml文件,则可以使用此类加载文件并获取容器对象。
FileSystemXmlApplicationContext:与ClassPathXmlApplicationContext相似,除了可以从文件系统中的任何位置加载xml配置文件。
Web应用程序的AnnotationConfigWebApplicationContext和XmlWebApplicationContext。
通常,如果您正在使用Spring MVC应用程序,并且您的应用程序配置为使用Spring Framework,则在启动应用程序和请求Bean时会初始化Spring IoC容器,并自动注入依赖项。
但是,对于独立应用程序,您需要在应用程序中的某个位置初始化容器,然后使用它来获取spring bean。
Spring Bean
Spring Bean没什么特别的,我们通过Spring容器初始化的Spring框架中的任何对象都称为Spring Bean。
如果通过提供配置元数据信息将其配置为通过容器初始化,那么任何普通的Java POJO类都可以是Spring Bean。
Spring Bean 范围
Spring Bean定义了五个作用域。
单例–将为每个容器创建一个bean实例。
这是spring bean的默认范围。
使用此范围时,请确保Bean没有共享的实例变量,否则可能会导致数据不一致问题。prototype –每次请求bean时都会创建一个新实例。
要求–与原型范围相同,但应用于网络应用程序。
将为每个HTTP请求创建一个新的bean实例。session –容器将为每个HTTP会话创建一个新bean。
global-session –用于为Portlet应用程序创建全局会话Bean。
Spring Framework是可扩展的,我们也可以创建自己的范围。
但是,大多数时候我们对框架提供的范围感到满意。
Spring Bean配置
Spring Framework提供了三种方法来配置要在应用程序中使用的bean。
基于注释的配置–通过使用@Service或者@Component注释。
范围详细信息可以通过@Scope注释提供。基于XML的配置–通过创建Spring Configuration XML文件来配置Bean。
如果您使用的是Spring MVC框架,则可以通过在web.xml文件中编写一些样板代码来自动加载基于xml的配置。基于Java的配置–从Spring 3.0开始,我们可以使用Java程序配置Spring Bean。
用于基于Java的配置的一些重要注释是@ Configuration,@ ComponentScan和@Bean。
Spring IoC和Spring Bean示例项目
让我们通过一个简单的Spring项目来查看Spring IoC容器和Spring Bean配置的不同方面。
对于我的示例,我正在Spring Tool Suite中创建一个Spring MVC项目。
如果您不熟悉Spring Tool Suite和Spring MVC,请阅读带有Spring Tool Suite的Spring MVC教程。
最终的项目结构如下图所示。
让我们一一看一下Spring IoC和Spring Bean项目的不同组件。
基于XML的Spring Bean配置
MyBean是一个简单的Java POJO类。
package com.theitroad.spring.beans;
public class MyBean {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Spring配置XML文件
servlet-context.xml代码:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="https://www.springframework.org/schema/mvc"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="https://www.springframework.org/schema/beans"
xmlns:context="https://www.springframework.org/schema/context"
xsi:schemaLocation="https://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
https://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
https://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/"
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/"
<beans:property name="suffix" value=".jsp"
</beans:bean>
<context:component-scan base-package="com.theitroad.spring"
<beans:bean name="myBean" class="com.theitroad.spring.beans.MyBean" scope="singleton" ></beans:bean>
</beans:beans>
注意,MyBean是使用bean元素配置的,作用域为单例。
基于注释的Spring Bean配置
package com.theitroad.spring.beans;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.web.context.WebApplicationContext;
@Service
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class MyAnnotatedBean {
private int empId;
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
}
使用@Service配置MyAnnotatedBean,并将范围设置为Request。
Spring IoC控制器类
HomeController类将处理对应用程序主页的HTTP请求。
我们将通过WebApplicationContext容器将Spring bean注入此控制器类。
package com.theitroad.spring.controller;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.theitroad.spring.beans.MyAnnotatedBean;
import com.theitroad.spring.beans.MyBean;
@Controller
@Scope("request")
public class HomeController {
private MyBean myBean;
private MyAnnotatedBean myAnnotatedBean;
@Autowired
public void setMyBean(MyBean myBean) {
this.myBean = myBean;
}
@Autowired
public void setMyAnnotatedBean(MyAnnotatedBean obj) {
this.myAnnotatedBean = obj;
}
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
System.out.println("MyBean hashcode="+myBean.hashCode());
System.out.println("MyAnnotatedBean hashcode="+myAnnotatedBean.hashCode());
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
}
部署描述符
我们需要为Spring Framework配置应用程序,以便配置元数据将被加载并且上下文将被初始化。
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="https://java.sun.com/xml/ns/javaee" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- The definition of the Root Spring Container shared by all Servlets and Filters --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/root-context.xml</param-value> </context-param> <!-- Creates the Spring Container shared by all Servlets and Filters --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Processes application requests --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
上面的几乎所有配置都是STS工具自动生成的样板代码。
运行Spring IoC Bean示例应用程序
现在,当您启动Web应用程序时,将加载主页,并在控制台中多次刷新页面时在控制台中打印以下日志。
MyBean hashcode=118267258 MyAnnotatedBean hashcode=1703899856 MyBean hashcode=118267258 MyAnnotatedBean hashcode=1115599742 MyBean hashcode=118267258 MyAnnotatedBean hashcode=516457106
请注意,将MyBean配置为单例,因此容器始终返回相同的实例,并且哈希码始终相同。
同样,对于每个请求,将使用不同的哈希码创建MyAnnotatedBean的新实例。
基于Java的Spring Bean配置
对于独立应用程序,我们可以使用基于注释以及基于XML的配置。
唯一的要求是在使用程序之前在程序中的某处初始化上下文。
package com.theitroad.spring.main;
import java.util.Date;
public class MyService {
public void log(String msg){
System.out.println(new Date()+"::"+msg);
}
}
MyService是带有某些方法的简单Java类。
package com.theitroad.spring.main;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value="com.theitroad.spring.main")
public class MyConfiguration {
@Bean
public MyService getService(){
return new MyService();
}
}
基于注释的配置类,将用于初始化Spring容器。
package com.theitroad.spring.main;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyMainClass {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(
MyConfiguration.class);
MyService service = ctx.getBean(MyService.class);
service.log("Hi");
MyService newService = ctx.getBean(MyService.class);
System.out.println("service hashcode="+service.hashCode());
System.out.println("newService hashcode="+newService.hashCode());
ctx.close();
}
}
一个简单的测试程序,其中我们初始化AnnotationConfigApplicationContext上下文,然后使用getBean()方法获取MyService的实例。
注意,我两次调用了getBean方法并打印了哈希码。
由于没有为MyService定义范围,因此应为单例,因此两个实例的哈希码应相同。
当我们运行上面的应用程序时,我们得到以下控制台输出,以确认我们的理解。
Sat Dec 28 22:49:18 PST 2013::Hi service hashcode=678984726 newService hashcode=678984726
如果您正在寻找基于XML的配置,只需创建Spring XML配置文件,然后使用以下代码片段初始化上下文。
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
MyService app = context.getBean(MyService.class);

