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);