Spring IoC,Spring Bean示例教程
欢迎来到Spring IoC示例教程。Spring Framework基于Inversion of Control原理。依赖注入是在应用程序中实现IoC的技术。
Spring IoC
今天我们将研究Spring IoC Container。我们也将通过Spring Bean。下面是快速导航到Spring IoC教程不同部分的目录。
Spring IoC Container
Spring IoC是实现Object依赖关系之间松散耦合的机制。要在运行时实现对象的松散耦合和动态绑定,对象依赖项将由其他汇编器对象注入。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 Framework提供了许多有用的ApplicationContext实现类,我们可以使用它们来获取spring上下文,然后是Spring Bean。
我们使用的一些有用的ApplicationContext实现是;
- AnnotationConfigApplicationContext:如果我们在独立的Java应用程序中使用Spring并使用Configuration的注释,那么我们可以使用它来初始化容器并获取bean对象。
- ClassPathXmlApplicationContext:如果我们在独立应用程序中有spring bean配置xml文件,那么我们可以使用这个类来加载文件并获取容器对象。
- FileSystemXmlApplicationContext:这类似于ClassPathXmlApplicationContext,除了可以从文件系统中的任何位置加载xml配置文件。
- Web应用程序的AnnotationConfigWebApplicationContext和XmlWebApplicationContext。
通常,如果您正在使用Spring MVC应用程序并且您的应用程序配置为使用Spring Framework,则Spring IoC容器会在应用程序启动时初始化,并且在请求Bean时,会自动注入依赖项。
但是,对于独立应用程序,您需要在应用程序中的某个位置初始化容器,然后使用它来获取spring bean。
春豆
Spring Bean并不特别,我们通过Spring容器初始化的Spring框架中的任何对象都称为Spring Bean。任何普通的Java POJO类都可以是Spring Bean,如果它被配置为通过容器通过提供配置元数据信息来初始化。
Spring Bean Scopes
为Spring Beans定义了五个范围。
- singleton - 只为每个容器创建一个bean实例。这是spring bean的默认范围。使用此范围时,请确保bean没有共享实例变量,否则可能导致数据不一致问题。
- prototype - 每次请求bean时都会创建一个新实例。
- 请求 - 这与原型范围相同,但它意味着用于Web应用程序。将为每个HTTP请求创建一个新的bean实例。
- session - 将为容器的每个HTTP会话创建一个新bean。
- global-session - 用于为Portlet应用程序创建全局会话Bean。
Spring Framework是可扩展的,我们也可以创建自己的范围。但是,大多数情况下,我们对框架提供的范围很好。
Spring Bean配置
Spring Framework提供了三种配置应用程序中使用的bean的方法。
- 基于注释的配置 - 使用@Service或@Component注释。可以使用@Scope注释提供范围详细信息。
- 基于XML的配置 - 通过创建Spring配置XML文件来配置bean。如果您使用的是Spring MVC框架,则可以通过在web.xml文件中编写一些样板代码来自动加载基于xml的配置。
- 基于Java的配置 - 从Spring 3.0开始,我们可以使用java程序配置Spring bean。用于基于Java的配置的一些重要注释是@Configuration,@ ComponentScan和@Bean。
Spring IoC和Spring Bean示例项目
让我们看一下Spring IoC容器和Spring Bean配置的不同方面,以及一个简单的Spring项目。
在我的例子中,我在Spring Tool Suite中创建了一个Spring MVC项目。如果您不熟悉Spring Tool Suite和Spring MVC,请阅读Spring Tool Suite的Spring MVC Tutorial。
最终的项目结构如下图所示。
让我们逐个查看Spring IoC和Spring Bean项目的不同组件。
基于XML的Spring Bean配置
MyBean是一个简单的Java POJO类。
package com.journaldev.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="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
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">
<!-- 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.journaldev.spring" />
<beans:bean name="myBean" class="com.journaldev.spring.beans.MyBean" scope="singleton" ></beans:bean>
</beans:beans>
请注意,MyBean是使用bean
范围为singleton的元素配置的。
基于注释的Spring Bean配置
package com.journaldev.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;
}
}
MyAnnotatedBean使用@Service配置,范围设置为Request。
Spring IoC控制器类
HomeController类将处理应用程序主页的HTTP请求。我们将通过WebApplicationContext容器将Spring bean注入此控制器类。
package com.journaldev.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.journaldev.spring.beans.MyAnnotatedBean;
import com.journaldev.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="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://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.journaldev.spring.main;
import java.util.Date;
public class MyService {
public void log(String msg){
System.out.println(new Date()+"::"+msg);
}
}
MyService是一个带有一些方法的简单java类。
package com.journaldev.spring.main;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(value="com.journaldev.spring.main")
public class MyConfiguration {
@Bean
public MyService getService(){
return new MyService();
}
}
基于注释的配置类,将用于初始化Spring容器。
package com.journaldev.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);
这就是Spring IoC示例教程,Spring Bean Scopes和Configuration详细信息。从下面的链接下载Spring IoC和Spring Bean示例项目,并使用它来更好地理解。
原创翻译 原文:https://www.journaldev.com/2461/spring-ioc-bean-example-tutorial