Spring 框架入门教程
1. 1. Spring 框架 2. 2. Spring 5 3. 3. Spring WebFlux 4. 4. 先介绍一下 Spring 5. 5. 什么是 Spring 依赖注入 6. 6. 什么是 Spring IoC 容器 和 Bean 7. 7. Spring Bean 的生命周期 8. 8. Spring REST 开发 9. 9. Spring REST XML 10. 10. Spring RestTemplate 开发 11. 11. Spring AOP 切面编程 12. 12. Spring AOP 方法调优 13. 13. Spring 注解详解 14. 14. Spring 核心注解之 @Autowired 15. 15. Spring 核心注解之 @RequestMapping 16. 16. Spring MVC 开发样例 17. 17. Spring MVC 开发指南 18. 18. Spring MVC 异常处理机制 19. 19. Spring MVC Validator 20. 20. Spring MVC 拦截器 21. 21. Spring MVC 文件上传 22. 22. Spring MVC 国际化(i18n) 23. 23. Spring MVC Hibernate MqSQL 24. 24. Spring ORM 25. 25. Spring ORM JPA 26. 26. Spring Data JPA 27. 27. Spring 事务管理 28. 28. 常用的 Spring JdbcTemplate 29. 29. Spring Security 简介 30. 30. Spring Security 教程 31. 31. Spring Security UserDetailsService 32. 32. Spring MVC 登录注销简单案例 33. 33. Spring Security Roles 34. 34. Spring Boot Tutorial 35. 35. Spring Boot Components 36. 36. Spring Boot CLI Hello World 37. 37. Spring Boot Initilizr Web 38. 38. Spring Boot Initilizr IDE 39. 39. Spring Boot Initilizr CLI 40. 40. Spring Boot Initilizr Tools 41. 41. Spring Boot MongoDB 42. 42. Spring Boot Redis Cache 43. 43. Spring Boot 常见面试问题 44. 44. Spring Batch 45. 45. Spring Batch 批处理示例 46. 46. Spring AMQP 47. 47. Spring RabbitMQ 48. 48. Spring AMQP RabbitMQ 49. 49. Apache ActiveMQ 安装与启动 50. 50. Spring ActiveMQ 教程 51. 51. Spring ActiveMQ 示例 52. 52. Spring JDBC 53. 53. Spring DataSource JNDI 54. 54. Spring Hibernate 55. 55. Spring Primefaces JPA 56. 56. Spring Primefaces MongoDB 57. 57. Spring Primefaces Hibernate 58. 58. SpringRoo Primefaces Hibernate 59. 59. Spring JSF 60. 60. Spring JDF Hibernate 61. 61. Spring Data MongoDB 62. 62. Spring 常见面试问题

6. 什么是 Spring IoC 容器 和 Bean

欢迎使用Spring Ioc示例教程。Spring框架是基于逆控制原理构建的。依赖注入是在应用程序中实现IoC的技术。

控制反转

今天我们来看看Spring Ioc容器。我们还将经历Spring Bean。下面是目录,可以快速导航到Spring Ioc教程的不同部分。

  1. 控制反转
  2. Spring Bean
  3. Spring Bean示波器
  4. Spring Bean配置
  5. Spring Ioc和Spring Bean示例
    1. 基于XML的Spring Bean配置
    2. 基于注解的Spring Bean配置
    3. 基于Java的Spring Bean配置

Spring IoC容器

Spring Ioc是实现对象依赖关系之间松耦合的机制。为了在运行时实现对象的松耦合和动态绑定,对象依赖关系由其他汇编对象注入。Spring Ioc容器是一个注射将依赖项放入一个对象中,并使其为我们的使用做好准备。我们已经研究过如何使用Spring注射依赖在我们的应用程序中实现IoC。

Spring Ioc容器类是org.springframework.beans and org.springframework.context packages. Spring IoC container provides us different ways to decouple the object dependencies.

BeanFactory is the root interface of Spring IoC container. ApplicationContext is the child interface of BeanFactory interface that provide Spring AOP features, i18n etc.

的一些有用的子接口ApplicationContext are ConfigurableApplicationContext and WebApplicationContext. Spring Framework provides a number of useful ApplicationContext implementation classes that we can use to get the spring context and then the Spring Bean.

我们使用的一些有用的ApplicationContext实现是;

  • 注解配置应用程序上下文:如果我们在独立的java应用程序中使用Spring并使用注解进行配置,那么我们可以使用它初始化容器并获取bean对象。
  • ClassPathXmlApplicationContext:如果我们在独立应用程序中有Spring Bean配置xml文件,那么我们可以使用这个类来加载文件并获取容器对象。
  • FileSystemXmlApplicationContext:这与ClassPathXmlApplicationContext类似,只是可以从文件系统中的任何位置加载xml配置文件。
  • 注解ConfigWebApplicationContextXmlWebApplicationContext对于web应用程序。

通常,如果您正在处理Spring Mvc应用程序,并且您的应用程序被配置为使用springframework,Spring Ioc容器在应用程序启动时初始化,当请求bean时,依赖关系会自动注入。

但是,对于独立的应用程序,您需要在应用程序中的某个地方初始化容器,然后使用它来获取Spring Bean。

Spring Bean

Spring Bean没有什么特别的,Spring框架中任何通过Spring容器初始化的对象都被称为Spring Bean。如果可以通过一个普通的Java类配置来初始化一个普通的POJO容器。

Spring Bean示波器

为Spring Bean定义了五个作用域。

  1. 独生子女–;每个容器只创建一个bean实例。这是Spring Bean的默认范围。在使用这个范围时,请确保bean没有共享的实例变量,否则可能会导致数据不一致的问题。
  2. 原型–;每次请求bean时都会创建一个新实例。
  3. 请求–;这与prototype scope相同,但是它是用于web应用程序的。将为每个HTTP请求创建一个新的bean实例。
  4. 阶段–;容器将为每个HTTP会话创建一个新的bean。
  5. 全球会议&#这用于为Portlet应用程序创建全局会话bean。

Spring框架是可扩展的,我们也可以创建自己的作用域。然而,大多数时候我们对框架提供的范围很在行。

Spring Bean配置

springframework提供了三种方法来配置要在应用程序中使用的bean。

  1. 基于注解的配置–;使用@Service或@Component注解。范围详细信息可以通过@Scope注解提供。
  2. 基于XML的配置&#通过创建Spring配置XML文件来配置bean。如果您使用的是Spring Mvc框架,那么可以通过编写一些锅炉板代码来自动加载基于xml的配置web.xml文件文件。
  3. 基于Java的配置&#从spring3.0开始,我们可以使用java程序配置Spring Bean。@Bean和@Scan注解用于一些基于@ComponentBean的配置。

Spring Ioc和Spring Bean示例项目

让我们用一个简单的Spring项目看看Spring Ioc容器和Spring Bean配置的不同方面。

对于我的例子,我正在Spring工具套件中创建一个Spring Mvc项目。如果您不熟悉Spring工具套件和Spring Mvc,请阅读SpringMVC教程和Spring工具套件.

最终的项目结构如下图所示。

让我们逐一看看Spring Ioc和Spring Bean项目的不同组件。

基于XML的Spring Bean配置

MyBean是一个简单的javapojo类。


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-上下文.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>
		<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" scope="singleton" ></beans:bean>
	
</beans:beans>

请注意,MyBean是使用bean element with scope as 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配置的,scope设置为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";
	}
	
}

配置描述符

我们需要为springframework配置应用程序,以便加载配置元数据并初始化上下文。


<?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 Iocbean示例应用程序

现在,当您启动web应用程序时,主页将被加载,并且在控制台中,当您多次刷新页面时,将打印以下日志。


MyBean hashcode=118267258
MyAnnotatedBean hashcode=1703899856
MyBean hashcode=118267258
MyAnnotatedBean hashcode=1115599742
MyBean hashcode=118267258
MyAnnotatedBean hashcode=516457106

注意,MyBean被配置为单例,因此容器总是返回相同的实例,而hashcode总是相同的。类似地,对于每个请求,将使用不同的哈希代码创建MyAnnotatedBean的新实例。

基于Java的Spring Bean配置

我们也可以将基于XML的配置用于基于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 context and then using getBean() method to get the instance of MyService.

请注意,我调用getBean方法两次并打印哈希代码。因为没有为MyService定义作用域,所以它应该是一个singleton,因此两个实例的hashcode应该是相同的。

当我们运行上述应用程序时,我们得到以下控制台输出,以确认我们的理解。


Sat Dec 28 22:49:18 PST 2013::Hi
service hashcode=678984726
newService hashcode=678984726

如果您正在寻找基于XML的配置,只需创建springxml配置文件,然后使用以下代码片段初始化上下文。


ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        MyService app = context.getBean(MyService.class);

以上是Spring Ioc示例教程、Spring Bean作用域和配置细节的全部内容。从下面的链接下载Spring Ioc和Spring Bean示例项目,并使用它来更好地理解它。

参考文献:IOSpring国际奥委会网页