Spring原理简介

Spring安装配置教程 1.Spring简介 Spring是一个开放源代码的设计层面框架,他解决的是业务逻辑层和其他各层的松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson创建。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。 2002 Rod Johnon <Ex... 阅读详情

Spring简介

Spring的历史

 Spring的基础架构起源于2000年早期,创始人为毕业于悉尼大学的音乐学博士RodJohnson。2003年2月,Spring架构正式成为开源项目,并发布于SourcesForge中。

Spring工作原理

 Spring是一个轻量级的控制反转(IoC) 和面向切面(AOP)的容器框架。我们不需要通过new关键词创建对象,而是在配置文件中配置JavaBean。当对象与对象之间有依赖关系的时候,我们也只需要在配置文件中把依赖关系体现出来,这些被配置的Bean将会纳入Spring管理,放置于Spring容器中。我们只需要写很少量的代码便可得到Spring容器,并且从Spring容器中得到配置的JavaBean。这种解决依赖性的方法即控制反转(IOC, 即Inversion of Control)或者依赖注入(Dependency Injection), 从技术上来说,就是用某种容器组织相互依赖的对象。除了10C之外,Spring还可以将分散在系统的公共代码统一组织起来,在运行的时候加入到系统中,这就是AOP(面向切面编程)。

Spring框架简介

Spring是用于简化企业应用程序开发过程的开源框架,属于轻量级的控制反转(I0C)和面向切面编程(AOP, 即Aspeet Oriented Proraming)的容器框架,解决了J2EE开发中许多常见的问题。我们需要了解一 下Spring中的一 些名词:
(1)轻量级:以所占大小及系统开销分析,Spring属于轻量级。整个Spring框架可以打包为1M左右的JAR包,且系统开销较小。同时,Spring为非侵入式,若系统基于Spring开发,其所含的对象一般不依赖于Spring的类。
(2)I0C: IOC使对象被动接受依赖类, 而并非主动获取。也就是说,告诉Spring“你”是什么,“你”需要什么对象,然后Spring会在系统运行到适当的时候,把“你”要的对象主动给“你”,同时也把“你”交给其他需要“你”的对象。所有的类的创建、销毁都由Spring来控制,控制对象生存周期的不再是引用它的对象,而是Spring。对于某个具体的对象而言,使用Spring之前是它控制其他对象,现在是所有对象都被Spring控制,所以叫控制反转。在系统运行中,动态的向某个对象提供它所需要的其他对象,这一点是通过DI (依赖注入)实现的。
(3)AOP:面向切面编程(也叫面向方面编程),关注系统的横向切面。通俗点说就是把代码“切开”,然后在需要的位置上动态加入公共代码。比如日志或者事务支持。
(4)容器: Spring 是一个包含且管理系统对象生命周期和配置的容器,在使用Spring应用开发的时候,几乎所有的JavaBean 对象都需要Spring来“盛放”。Spring容器的作用是管理对象。
(5)Spring框架: Spring能够通过简单的组件组合为复杂的系统。Spring框架为分层架构,由7个定义良好的模块组成,各模块构建于核心容器之上,核心容器定义了创建、配置及管理Bean的方式。

  1. Spring Core,核心容器,用于提供Spring框架的其主要基本功能,其主要为组件为BonFoctory,是工厂 模式的实现。BeanFactory使用反向控制(ioc将模式将应用程序的配置及依赖性规范与实际应用程序代码分开。
  2. Sping Context: 核心楼块的BanFatory使Spring成为容器,上下文(Context)模块使其成为框架。此模块扩展TBeanFactory的概念,增加了对国际化18即Internationalization)消息、事件的传播以及验证的支持: 同时,此模块提供诸多企业服务,如电子邮件、 JNDI访问、 EJB集成、 远程以及时序调度(Scheduling)服务,支持对模版框架(如Velocity、 FreeMarker)的集成。
  3. Spring AOP :通过配置管理特性,Spring AOP模块将面向切面编程功能集成至框架中,使Spring框 架管理的任何对象均支持AOP. Spring AOP模块向基于Spring的应用程序中的对象提供事务管理服务。此模块无需依赖于EJB组件,可以使用Spring AOP将声明式事务管理集成至应用程序中。
  4. Spring DAO: JDBC DAO抽象层提供了意义重大的异常层次结构,简化了错误处理过程并极大地减少了需要编写的异常代码(如打开或关闭连接),运用此结构可以管理异常、处理不同数据库供应商抛出的错误消息。SpringDAO的面向JDBC异常遵从通用的DAO异常层次结构。
  5. Spring ORM :Spring框架中插入了若FORM框架,提供ORM的对象关系工具,包括JDO. Hibernate以及iBatis sqL Map,都遵从Spring的通用事务及DAO弄常层次结构。
  6. Spring Web: Web上下文模块建立在应用程序上下文模块之上,向基于eb的应用程序提供上下文,因而Sprig框架 支持5truts集成。同时, Teb模块简化了清求的处理过程以及将请求参数绑定至域对象的工作。
  7. Sprins wC iwC 柜架是个全功能的构建 Veb应用程序的WVC 实现。通过家略接口,mvc框架变为高度可匹配,它容纳了大量试图技术,包括jsp、Velocity、Titles、iText及POI。

MyEclipse添加spring支持如下图:

1.右键选择需要添加spring的项目:选择MyEclipse
在这里插入图片描述2.然后选择Add Spring
在这里插入图片描述
3.选择spring的版本号
在这里插入图片描述
这样就可以完成所需要的项目spring添加。

Spring Bean封装机制

Spring Bean

 Spring以Bean的方式管理所有的组件,J2EE 的全部组件都使用Bean管理。在Spring中,除了标准的JavaBean,其他任何对象和组件都可以作为Bean.应用中各层的对象均由Spring管理,对象以Bean方式存在。Spring负责创建Bean的实例并管理其生命周期,Bean运行于Spring的容器。Spring上下 文是生产Bean的工厂,Bean是Spring工厂生产的实例。Spring产生工厂时,需要确定每个Bean的实现类; Bean实例的使用者面向接口,因此无须关心Bean实例的实现类。Spring工厂负责维护Bean实例的实例化,使用者则无须关心。Bean的定义通常使用XML配置文件,正确定义的Bean由Spring提 供实例化以及依赖关系的注入等。最简单的Spring配置文件代码如下:

<?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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
</beans>

 Spring的schemaLocation详细规定了Spring配置文件的合法元素,各元素出现的先后顺序、各元素的合法子元素以及合法属性等。
 增加对实体对象管理的Bean,配置文件代码如下:

<?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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
	<bean id="user" class="com.hr.entity.UserVo" abstract="false" lazy-init="default" autowire="default"/>
</beans>

上述代码中定义了UserVo对象。xml中Bean节点的部分属性如下:

<bean 
id="beanId" 
name="beanName" 
class="beanClass" 
parent="parentBean" 
abstract="true | false" 
scope="prototype | singleton"
lazy-init="no | btName | by Type | construcyor | auto detect |default"/>
</beans>

Bean的属性如下表:

属性含义
idBean的唯一标识名,必须为合法的XML ID, 在整个XML文档中唯,如果没 有特殊需要,我们在标识一个Bean的时候,一般推荐使用id.
name用于为id创建一个或多 个别名,可以是任意字母或者符号,多个别名之间以逗号或空格分隔。
class用于定义类的全限定名(包名加类名),Spring在创建对象的时候需要用到此属性,因此该属性不能指定接口。
parent子类Bean定义其所引用的父类Bean,继承父类的所有属性。值得一提的是,在写代码的时候,即便是两个类之间没有继承关系,我们同样可以使用该属性。
abstract用于定义Bean是否为抽象Bean,默认为false,表示此Bean将不会被实例化。一般用于父类Bean,可以在子类继承的时候使用。
scope用于定义Bean的作用域,singleton表示 在每个Spring IoC容 器中一个bean定义对应一个对象实例,即Spring使用 单例模式获取实例。prototype表示一个bean定义对应多个对象实例,即非单例模式
lazy-init用于定义Bean是否实现初始化,默认为default。若为true,将在BeanFactory启动时初始化所有Singleton Bean; 若为false, 则在Bean请求时创建Singleton Bean
autowire用于定义Bean的自动装配方式,默认为default,包括不使用自动装配功能、通过Bean的属性名实现自动装配、通过Bean的类型实现自动装配、通过Bean类的反省(Introspection)机制决定选择使用constructor或者byType。

Application Context

 Spring包括两种不同的容器: BeanFactory 和ApplicationContexto.BeanFactory提供基本的I0C支持; ApplicationContext则基于BeanFactory,提供应用程序框架服务。Spring提供了BeanFactory与ApplicationContext 的多个实现。ApplicationContext包括BeanFactory 的全部功能,除非应用程序对性能要求很高时才考虑BeanFactory,其他情况下建议优先使用ApplicationContext。
应用中出现多个配置文件时,应采用BeanF actory的子接口ApplicationContext创建Spring容器的代码如示例:

//搜索classpath路径,以classpath路径下的applicationContext . xml创建对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext . xml");

 在实际应用中,会将Spring配置分别放在不同的配置文件中,如果一个应用中有两个配置文件application. xml和bean. xml,则创建容器实例的方法如示例1.4所示。

//搜索clsspath路径,以claspath路径 下的
//applicationContext。xm1和bean. xml创建Applicat ionContext.
ApplicationContext applicationContext = new ClassPathXmlApplicationContext (new Stringl]{"pplicationContext.xm1", "bean.xm1");

ApplicationContext接口包括以下3个重要方法:

(1)containsBean (String name)方法。

//判断Spring容器是否包含ID为user 的Bean
boolean flag-applicationContext.containsBean ("user");

(2)getBean(String name)方法。

//返回ID为user的Bean
UserVo userBean = (UserVo) applicationContext.getBean ("user");
//该方法的功能是从Spring容器中获取一个对象,该方法的参数可以是Spring配置文件中Bean的d或者name,如果name指定了多个标识,只需传入一个标识。

(3)getType(String name)方法。

//返回:ID为user的类型
Class beanType= applicationContext.getType ("user");

示例:从Spring容器中获取一个user对象,并输出user的信息。

package com.hr.controller;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.hr.entity.UserVo;

public class test {
	public static void main(String[] args) {
		ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
	    UserVo user = (UserVo) application.getBean("user");
	    user.setName("张三");
	    user.setAge(12);
	    System.out.print(user);
	}

}

Spring DI和IOC

什么是Spring的依赖注入

 在生活中,依靠别人或者别的事务而不能独立或者自立,我们称之为依赖。
 依赖指的是二个实例之间的关系。其中一个实例是独立的,另一个实例是非独立的(依赖的),它依靠另一个实例。比如计算机对象,它包含主机对象和显示器对象。如果没有主机对象或者显示器对象,则计算机对象就是不完整的,不能正常使用,我们就说计算机对象依赖于主机对象和显示器对象。
 计算机对象离不开主机对象和显示器对象,程序在运行过程中,我们必须给计算机对象提供它所需要的主机对象和显示器对象,把主机对象和显示器对象像“打针”一样提供给计算机对象,这个过程就叫做注入。也就是说,如果一个对象需要另外一个对象才能正常使用,我们在程序运行的时候,给该对象提供它所需要的对象,这就是“依赖注入”。我们知道,Spring将会管理几乎所有的Bean对象,而对象与对象之间可能存在依赖关系,在程序运行过程中,Spring把我们所需要的对象都拼装好,这就是Spr ing的依赖注入。
 在传统的Java设计中,当Java实例的调用者创建被调用的Java实例时,要求被调用的Jave类出现在调用者的代码中,二者之间无法实现松耦合。工厂 模式则对此进行了改进,使调用者无须关心被调用者的具体实现过程,只要获得符合某种标准(接口)的实侧即可使用。其调用的代码面向接口编程,支持调用者与被调用者解耦,因此工厂模式得以大范围地使用,但在工厂模式中,调用者需要自行定位工厂,与特定工厂耦合,所以仅在一定程度上实现了调用者与被调用者的解耦。Spring 的出现使调用者无须自行定位工厂,当程序运行至需要被调用者时,系统将自动提供被调用者实例。事实上,调用者与被调用者均由Spring管理,二者之间的依赖关系由Spring提供。

示例:
 设计一个主机类(MainFrame)

public class MainFrame {
   private String modelType;
   public void printMainFrameInfo(){
	   System.err.println("主机型号"+modelType);
   }
public String getModelType() {
	return modelType;
}
public void setModelType(String modelType) {
	this.modelType = modelType;
} 
}

 接口(Display)

package com.hr.service;
public interface Display {
   public void printDisplayInfo();
}

 业务实现层(impl)

package com.hr.service.impl;
import com.hr.service.Display;
public class SamSungDisplay implements Display{
	public void printDisplayInfo() {
		// TODO Auto-generated method stub
		System.err.println("显示器:三星");
	}
}
package com.hr.service.impl;
import com.hr.service.Display;
public class LgDisplay implements Display{
	public void printDisplayInfo() {
		// TODO Auto-generated method stub
		System.err.println("显示器:Lg");
	}
}

 计算机类

package com.hr.controller;
import com.hr.entity.MainFrame;
import com.hr.service.Display;
public class Computer {
   private MainFrame mainFrame;
   private Display display;
   public void printComputerInfo(){
	   System.err.println("计算机配置如下:");
	   mainFrame.printMainFrameInfo();
	   display.printDisplayInfo();
   }

public MainFrame getMainFrame() {
	return mainFrame;
}
public void setMainFrame(MainFrame mainFrame) {
	this.mainFrame = mainFrame;
}
public Display getDisplay() {
	return display;
}
public void setDisplay(Display display) {
	this.display = display;
}  
}

applicationContext.xml

<bean id="samsung" class="com.hr.service.impl.SamSungDisplay"/>
<bean id="lg" class="com.hr.service.impl.LgDisplay"/>
<bean id="mainFrame" class="com.hr.entity.MainFrame">
   <property name="modelType" value="三星高配主机"/>
</bean>
<!-- 计算机的配置 -->
<bean id="computer" class="com.hr.controller.Computer">
  <!-- 设置注入主机,name对应计算机的属性,ref对应所依赖的bean -->
  <property name="mainFrame" ref="mainFrame"/>
  <property name="display" ref="lg"/>
</bean>

输出

package com.hr.controller;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class appCon {
    public static void main(String[] args) {
		ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
		Computer computer = (Computer)application.getBean("computer");
		computer.printComputerInfo();
	}
}

结果如图:
在这里插入图片描述

设值注入方式

 设值注入是指通过setter方式传入被调用者的实例,所以Bean的属性要求有对应的setter和getter方法。此方式因简单直观而得以广泛使用。配置文件如下:

<!-- 计算机的配置 -->
<bean id="computer" class="com.hr.controller.Computer">
  <!-- 设置注入主机,name对应计算机的属性,ref对应所依赖的bean -->
  <property name="mainFrame" ref="mainFrame"/>
  <property name="display" ref="lg"/>
</bean>

构造注入方式

 构造注入是指通过构造方法完成依赖关系的注入,并非setter方法。将以上设值注入按构造注入重新实现,则需要在computer中增加带参构造方法,配置文件如下:

<!-- 计算机的配置 -->
<bean id="computer" class="com.hr.controller.Computer">
  <!-- 设置注入主机,ref对应所依赖的bean -->
  <constructor-arg index="0" ref="mainFrame"/>
  <constructor-arg index="0" ref="samsung"/>
</bean>

自动注入

 Spring容器可以自动注入(autowire)相互协作bean之间的关联关系。因此,如果可能的话,可以自动让Spring通过检查BeanFactory中的内容,来替我们指定bean的协作者(其他被依赖的bean)。由于autowire可以针对单个bean进行设置,因此可以让有些bean使用autowire,有些bean不采用。autowire的方便之处在减少或者消除属性或构造器参数的设置,这样可以简化配置文件,如果直接使用property和constructor-arg注入依赖的话,那么将总是覆盖自动装配,在xml配置文件中,可以在元素中使用autowire属性指定,如下表所示。

模式说明
no不使用自动装配。必须通过ref元素指定依赖,这是默认设置。由于显式指定协作者可以使配置更灵活、更清晰,因此对于较大的部署配置,推荐采用该设置。
byName根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致 的bean, 并将其与属性自动装配。
byType如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。如果存在多个该类型的bean,那么将会抛出异常,并指出不能使用byType方式进行自动装配。若没有找到相匹配的bean,则属性不会被设置。

配置文件如下:

<bean id="computer" autowire="byName" class="com.hr.controller.Computer">
  <property name="mainFrame" ref="mainFrame"/>
  <property name="display" ref="lg"/>
</bean>

 由于使用byName自动装配,容器会检查ID和Computer的两个属性mainFrame以及display名称匹配的Bean并注入,由于存在ID为mainFrame的Bean, 所以Computer的mainFrame属性被自动注入,而display是 显式注入,所以覆盖了display属性的自动注。

集合属性

 通过< list />、< set />、 < map />及< props />元素可以定义和设置与Java Collection类型对应List、Set、 Map及Properties的值。

示例:

//型对应List、Set、 Map及Properties的值。 
//示例1. 18中定义TestBean类,该类有四个属性,分别是List、Map、Properties, Set类型。
private List list;
private Map map;
private Properties properties;
private Set set;

 对于TestBean类的配置如下:

<bean id="TestBean" class="com.hr.controller.TestBean">
   <!-- list属性的配置 -->
   <property name="list">
     <list>
       <value>v1</value>
       <value>v2</value>
     </list>
   </property>
   <!-- map属性的配置 -->
   <property name="map">
     <map>
       <entry key="k1">
        <value>v1</value>
       </entry>
       <entry key="k2">
        <value>v2</value>
       </entry>
     </map>
   </property>
   <!-- prop属性的配置 -->
   <property name="prop">
     <props>
       <prop key="k1">str1</prop>
       <prop key="k2">str2</prop>
     </props>
   </property>
   <!-- set属性的配置 -->
   <property name="set">
     <set>
      <value>v1</value>
       <value>v2</value>
     </set>
   </property>
</bean>

 程序运行的时候,我们从Spring容器中获取testBean实例,该实例的四个集合属性中将会包含指定的对象。

Spring注入方式的比较

1.设值注入的特点
 对于习惯了传统JavaBean开发的程序员而言,通过setter方法设定依赖关系更加直观自然。当依赖关系(或继承关系)较复杂时,构造注入方式的构造函数相当庞大,且需要在构造函数中设定所有依赖关系,此时使用设值注入方式则简单快捷。除此之外,某些第三方类库要求组件必须提供默认的构造函数(如Struts中的Action),此时构造注入方式的依赖注入机制会突显局限性,难以完成预期的功能,必须通过设值注入实现。
2.构造注入的优点
 在构造期即创建完整、合法的对象,构造注入无疑是此Java设计原则的最佳响应者。
 而且构造注入还避免了编写繁琐的setter方法,所有的依赖关系都在构造函数中设定,使依赖关系集中呈现,可读性增加。由于不存在setter方法,而是在构造时由容器一次性设定依赖关系。因此,组件在创建之后即处于相对稳定状态,无需担心上层代码在调用过程中执行setter方法时破坏组件之间的依赖关系。对于Singleton模式组件,这种破坏将对整个系统产生重大的影响。通过构造注入,可以在构造函数中决定依赖关系的注入顺序。对于大量依赖外部服务的组件而言,依赖关系的获取顺序至关重要。

基于注解的容器配置

 基于注解(Annotation)的配置有越来越流行的趋势,Spring顺应这种趋势,从2.5版起提供了完全基于注解配置Bean、装配Bean的功能,可以使用基于注解的Spring IOC替换原来基于xml的配置。

使用@Component注解配置bean

 只需要在类的定义语句上加上一个@Component注解,就将该类定义为一个bean,如下:

@Component
public class Computer {
   private MainFrame mainFrame;
   private Display display;
   public void printComputerInfo(){
	   System.err.println("计算机配置如下:");
	   mainFrame.printMainFrameInfo();
	   display.printDisplayInfo();
   }
   }
@Component
public class MainFrame {
   private String modelType;
   public void printMainFrameInfo(){
	   System.err.println("主机型号"+modelType);
   }
 }
 @Component
 public class SamSungDisplay implements Display{
	public void printDisplayInfo() {
		// TODO Auto-generated method stub
		System.err.println("显示器:三星");
	}
}
 @Component
 public class LgDisplay implements Display{
	public void printDisplayInfo() {
		// TODO Auto-generated method stub
		System.err.println("显示器:Lg");
	}
}

 我们通过@Component注解分别将Computer 、MainFrame 、SamSungDisplay 、LgDisplay 配置成bean。bean名称默认为将第一个字母转换成小写的类名。如Computer 类的bean默认名称是computer。xml配置如下:

<bean id="computer" class="com.hr.controller.Computer"/>
<bean id="mainFrame" class="com.hr.entity.MainFrame"/>
<bean id="lgDisplay" class="com.hr.service.impl.LgDisplay"/>
<bean id="samSungDisplay" class="com.hr.service.impl.SamSungDisplay"/>

 @Component注解的唯一一个可选参数是value,用于指定bean的名称(即id,所以必须是唯一的),声明Computer类为一个bean,id为computer。如下:

@Component(value="computer")
public class Computer{}

 可以简写为:

@Component("computer")
public class Computer{}

 Spring还提供了更加细化的用于定义bean的注解形式:@Repository、@Service、@Controller,他们分别对应数据访问层bean,业务层bean和视图层bean。目前版本中,这些注解与@Computer的语义是一样的,完全通用,在Spring以后的版本中可能会给他们追加更多的语义。所以,我们推荐使用@Repository、@Service、@Controller来替代@Computer。

扫描@Component标注的类

 在使用@Component注解后,Spring容器必须启用类扫描机制,以找到所有使用@Component标注的类,将他们作为bean来管理。从Spring2.5开始,对context命名空间进行了扩展,提供了这一功能,请如下配置,引入context命名空间,并扫描bean:

<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-4.3.xsd
    <context:component-scan base-package="com.hr.controller.computer"></context:component-scan>
    </bean>

 Spring容器在初始化时会扫描<context:component-scan />标签的base-package属性指定的类包及其递归子包中所有的类。找出@Component标注的类,将他们配置成bean。然后,我们就可以通过Spring容器的工厂方法获取并使用bean了。如下:通过Spring容器获取Computer bean。

ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Computer c = ac.getBean(Computer.class);

使用@Scope注解配置bean的作用域

 @Scope用于定义bean的作用域,singleton表示 在每个Spring IoC容器中一个bean定义对应一个对象实例,即Spring使用 单例模式获取实例。prototype表示一个bean定 义对应多个对象实例,即非单例模式,我们常称作多例。默认情况下,Spring bean的作用域为singleton。如下:将Computer类配置成一个“多例”的bean :

@Component
@Scope(value="prototype")
public class Computer{}

可以简写为:

@Component
@Scope("prototype")
public class Computer{}

使用@Autowired注解

 从Spring 2.5版本起,Spring引入了@Autowired注解,它可以对类成员变量、方法及构造函数进行标注,以完成自动装配依赖的工作。如下:使用@Autowired为成员变量自动注入依赖。

@Component
@Scope("prototype")
public class Computer {
   @Autowired
   private MainFrame mainFrame;
   @Autowired
   private Display display;
   public void printComputerInfo(){
	   System.err.println("计算机配置如下:");
	   mainFrame.printMainFrameInfo();
	   display.printDisplayInfo();
   }
   }

 将@Autovired标注于实例凤性ainFrenedisploy上面,Sprin将直按采用Jave反射机制获取mainFrame和display属性的类型,再根据类型查找“唯一”匹配的bean来进行依赖自动注入(如果bean的类型与属性的类型相同,或者bean的类型是属性类型的子类型或接口实现,则类型匹配)。
 由于和mainFrame属性类型匹配的bean只有MainFrame个,所以自动装配依赖可以顺利进行。但是和display属性的类型匹配的bean有两个(SamSungDisplay和LgDisplay都实现了Display接口,而display属性类型正是 Display) ,此时Spring应用容器不知道该用哪一个bean为Computer的display属性注入依赖值,从而导致创建Computer bean失败,抛出BeanCreationException。
 那么如何解决根据类型返回多个ben导数的创建ban失败的问题呢?答案是指定需要注入的bean的名称。要为Computer bean的display属性注入三星显示器,就需要告诉Spring我们需要的是符合Display类型,且id为sanSungDisplay的bean。指定依赖bean名称的方法有二种:

  1. 把属性名称作为依赖bean名称。
  2. 使用@Qualifier注解明确指定依赖bean的名称。
     将display属性改为sanSungDisplay,当Spring应用容器根据属性类型返回多个bean时,会继续以反射的方式获得属性的名称sanSungDisplay,从而找到同名的bean。

如下:

@Component
@Scope("prototype")
public class Computer {
   @Autowired
   private MainFrame mainFrame;
   @Autowired
   private Display display;
   public void printComputerInfo(){
	   System.err.println("计算机配置如下:");
	   mainFrame.printMainFrameInfo();
	   sanSungDisplay.printDisplayInfo();
   }
   }

也可以使用setter方法,构造方法和其他的方法,根据参数类型和名称来注入依赖bean。如下:

@Component
@Scope("prototype")
public class Computer {
   private MainFrame mainFrame;
   private Display display;
   @Autowired
   public Computer(MainFrame mainFrame,Display sanSungDisplay){
	  super();
	  this.mainFrame = mainFrame;
	  this.display = sanSungDisplay;
   }
   .....
   }

使用@Qualifier注解为自动注入指定依赖bean的名称

 Spring允许我们通过@Qualifier注解指定注入Bean名称。
示例:

@Component
@Scope("prototype")
public class Computer {
   @Autowired
   private MainFrame mainFrame;
   @Autowired
   @Qualifier("sanSungDisplay")
   private Display display;
   public void printComputerInfo(){
	   System.err.println("计算机配置如下:");
	   mainFrame.printMainFrameInfo();
	   sanSungDisplay.printDisplayInfo();
   }
   }

使用@Qualifier注解为方法指定要注入的依赖bean的名称

@Component
@Scope("prototype")
public class Computer {
   private MainFrame mainFrame;
   private Display display;
   @Autowired
   public Computer(MainFrame mainFrame,@Qualifier("sanSungDisplay") Display sanSungDisplay){
	  super();
	  this.mainFrame = mainFrame;
	  this.display = sanSungDisplay;
   }
   .....
   }

**总结:**使用@Autowired注解自动装配依赖的过程如下:

  1. 首先根据属性的类型(或方法、构造方法参数的类型)在Spring应用的容器中查找类型匹配的bean。
  2. 如果没有类型匹配bean,抛出BeanCreationExecption;如果只有一个,则注入依赖,完成自动装配,如果不只一个,则继续执行步骤3。
  3. 如果通过@Qualifier指定了bean,则从所有符合类型的bean中返回指定的bean,完成自动装配;如果没有通过@Qualifier制定bean名称。则通过反射技术获取当前属性的名称作为bean名称返回指定的bean,完成自动装配。

使用@Resource注解注入依赖

 Spring不但支持 自己定义的@Component、@Scope、@Autowired、@Qulifier注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource、PostConstruct以及@PreDestroy。
 @Resource的作用相当于Autowired,只不过Autorired默认按DyType自动注入,@Rescurce默认按byName自动注入罢了。@Resource有两个属性是比较重要的,分别是name和type,Spring将@Resource注解的name属性解析为Bean的名字,面type属性则解析为Bean的类型。所以如果使用name属性,则使用byNane的自动注入策略,而使用type属性时则使用byType自动往入策略。如果既不指定nne也不指定type属性,这时将通过反射机制使用byNeme自动注入策略,如下:

@Component
@Scope("prototype")
public class Computer {
   @Resource
   private MainFrame mainFrame;
   @Resource(name="sanSungDisplay")
   private Display display;
   }

@PostConstruct 和@PreDestroy

 Spring容 器中的Bean是有生命周期的,Spring允 许在Bean在初始化完成后以及Bean销毁前执行特定的操作。JSR 250为初始化之后/销毁之前指定执行方法定义了两个注解类,分别是ePostConstruct和@PreDestroy,这两个注解只能应用于方法上。标注了PostConstruct注解的方法将在类实例化后调用,而标注了@PreDestroy的方法将在类销毁之前调用。如下:

@Component
@Scope("prototype")
public class Computer {
@PostConstruct
public void postConstruct1(){
  System.out.prinyln("执行postConstruct1");
}
@PreDestroy
public void PreDestroy1(){
  System.out.prinyln("执行postConstruct1");
}
}

 执行时,在bean被初始化时,会输出执行postConstruct1。在bean被销毁时,会输出执行postConstruct1。我们通常可以标注@PostConstruct的方法中完成一些资源初始化的工作,在标注了@PreDestroy的方法中完成一些释放资源的操作。

Spring框架详解(持续更新) Mybatis Spring SpringMVC详解 阅读详情

相关推荐

自组织映射神经网络(SOM)

目录 1 背景:自组织(竞争型)神经网络 2竞争学习的概念与原理 2.1 竞争学习的步骤 2.2 示例 3SOM典型结构 4SOM网的权值调整域 5 SOM Kohonen 学习算法 6 SOM示例 7SOM设计细节 7.1输出层设计 7.2输出层节点排列的设计 7.3 权值初始化问题 7.4学习率的设计 7.5设计拓扑领域 8SOM功能分析 8.1 保序映射 8.2数据压缩 8.3 特征提取 9自组织映射神经网络与K均值算法的区别...

weixin_39910711的博客 1万+

Spring安装和使用(Eclipse环境)

一、Spring框架概述        1、 什么是Spring             Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之...

汤庆 5万+

红外小目标检测新思路:当DETR遇上Mamba状态空间模型,速度提升3倍

本文探讨了将Mamba状态空间模型与DETR框架结合,用于解决红外小目标检测的难题。该创新方案通过线性复杂度的Mamba模块替代传统Transformer的自注意力机制,在保持高检测精度的同时,显著提升了推理速度,实现了实时性能的突破,为无人机巡检、安防监控等场景提供了高效解决方案。

hhh00的博客 664

手把手教你安装Spring+搭建Spring开发环境

为了让新手安装Spring时少走弯路,小编写下详细步骤(以win8,64位为例)。 请系好安全带,坐好扶稳。 一:安装eclipse 如果已经安装请忽略此步。 官网下载地址(64位):https://www.eclipse.org/downloads/download.php?file=/oomph/epp/oxygen/R2/eclipse-inst-win64.exe 点开...

csdnsjg的博客 6万+

Hand-Eye 标定误差分析:从理论到 C++ 实现

本文深入探讨了机器人手眼标定中的核心环节——误差分析。文章从AX=XB方程的理论残差出发,详细解析了旋转与平移误差的数学定义与物理意义,并提供了一个工业级的C++实现代码,用于计算重投影误差。通过误差分析,工程师可以量化标定精度,诊断问题根源,从而确保视觉引导机器人系统在实际应用中的可靠性与精确性。

c7d8e的博客 695

专栏二十:如何选择你的单细胞亚群的分辨率--ROGUE

ROGUE这是继chooseR后第二个计算单细胞亚群分辨率的内容,其实关于代码的运行很简单,网上已经有不少教程,重复这些就没意思了,这里主要是结合探讨一下这个算法。

m0_58549466的博客 981

Spring全面详解

Spring基础部分,适合Java开发者来看。或者学习者。编译器采用了IDEA2020.2.3比较新的一个版本。里面记录了很多东西,保持持续的更新,如果只是想下载Spring里面也提供了链接,和一些依赖jar链接。希望对你们有所帮助,对我有所提升!

想看什么文章都可以私信给我,综合性博客。 9791

【软件系统架构】系列四:嵌入式技术

嵌入式系统是以应用为中心、以计算机技术为基础,并将可配置与可裁剪的软硬件集成于一体的专用计算机系统。它需要满足功能、可靠性、成本、体积、功耗等方面的严格要求。 嵌入式系统一般由以下组成部分构成:

moton2017的博客 999

spring原理简介

spring原理简介

qq_27648971的博客 327

[系统安全] 十一.那些年的熊猫烧香及PE病毒行为机理分析

如果你想成为一名逆向分析或恶意代码检测工程师,或者对系统安全非常感兴趣,就必须要认真分析一些恶意样本。熊猫烧香病毒就是一款非常具有代表性的病毒,当年造成了非常大的影响,并且也有一定技术手段。本文将详细讲解熊猫烧香的行为机理,并通过软件对其功能行为进行分析,这将有助于我们学习逆向分析和反病毒工作。后续作者还将对其进行逆向调试,以及WannaCry勒索蠕虫、各种恶意样本及木马的分析。基础性文章,希望您喜欢!同时,本文部分实验参考姜晔老师的视频分析,真的非常佩服和值得去学习的一位老师。技术路上哪有享乐,为了提升安

杨秀璋的专栏 7327

高精度地图数据的结构

本文是个人在学习高精度地图数据结构的心得,主要是描述高精度地图的几层数据结构以及元数据信息。

qq_40664711的博客 5575

Spring AOP实现原理简介

AOP联盟标准AOP联盟将AOP体系分为三层,从三层结构可以看出,AOP实现方式有很多种,包括反射、元数据处理、程序处理、拦截器处理等,通过本节学习,你就会看到Spring AOP的实现使用的是Java语言本身的特性,即Java Proxy代理类、拦截器技术实现。AOP简介概念切面(Aspect) :官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”。连接点(Joinpoint)...

wyl6019的博客 7万+

DISK配置服务器软RAID工作任务(RAID1+BITLOCKER)-winserver4

DISK配置服务器软RAID工作任务(RAID1+BITLOCKER)-winserver4

新时代先锋的博客 7299

Spring Security简介和原理

Spring Security是 Spring提供的安全认证服务的框架。使用Spring Security可以帮助我 们来简化认证和授权的过程。--security启动器-->

0 1396

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Spring的简介和工作原理

一、简介 Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用,但是有些扩展是针对构建J2EE平台的web应用。Spring 框架目标是简化Java企业级应用开发,并通过POJO为基础的编程模型促进良好的编程习惯。 二、工作原理 Spring最核心的两个点就是IOC和AOP 1、 IoC(Inversion of control): 控制反转...

NPE2.0的博客 8771

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Spring——Spring中的AOP简介、原理

Spring——AOP学习 一、什么是AOP AOP(Aspect Oriented Programming),面向切面编程。AOP是OOP(Object Oriented Programming)面向对象编程的延续。 AOP是可以通过预编译方式和运行期动态代理的方式在不修改源代码的情况下给程序统一添加功能的一种技术。 AOP实际上是GoF(Gang of Four,GOF设计模式,四人组)的一种...

qq_43411550的博客 406

Spring的原理简介

在用ssh(Struts+Spring+Hibernate)实现的mvc模式中Spring是作为连接Struts和Hibernate的控制层。   与Spring框架相关的概念有以下:   轻量级:轻量级是针对重量级容器(EJB)来说的,Spring的核心包不到1M大小,而使用Spring的核心包所需的资源也很小,所以可以在小型设备中使用。   非侵入性:所有的框架都是提供

Javaweb开发,对日开发 1029

原理简介_Spring Cloud Bus 原理简介和实现

一、原理简介Spring Cloud Bus 使用轻量级的消息代理来连接微服务架构中的各个服务,可以将其用于广播状态更改(例如配置中心配置更改)或其他管理指令通常会使用消息代理来构建一个主题,然后把微服务架构中的所有服务都连接到这个主题上去,当我们向该主题发送消息时,所有订阅该主题的服务都会收到消息并进行消费。使用 Spring Cloud Bus 可以方便地构建起这套机制,所以 Spring C...

weixin_39850152的博客 303

spring之AOP简介与原理

   一、AOP基本情况         AOP 为Aspect Oriented Programming的缩写,面向切面编程,通过预编译方式和运行期动态代理实现程序的统一维护的一种技术。AOP是OOP(面向对象编程)的延续,是软件开发中的一个热点,也是Spring框架的一个重要内容,是函数编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提供...

qq_36697880的博客 408

Spring Security的原理简介

参考文章:Spring Boot框架整合Spring Security实现安全访问控制 SpringSecurity核心组件 Spring Security做JWT认证和授权--import SpringBoot中使用Shiro和JWT做认证和鉴权--import Spring Security的安全访问控制分为Authentication(认证)和Authorization(授权,...

justlpf的专栏 3715

Spring IOC底层原理简介

什么是IOC: 控制反转: 把对象创建和对象之间的调用过程交给Spring(目的:降低耦合度) 底层技术:XML解析,工厂模式(设计模式),反射。 (简单说下工厂模式;如下图 在第一个类中调用第二个类的方法 原始方法直接调用,但是缺点很明显 我们可以稍微改进一下: 设置一个工厂类 大幅度降低耦合度) 然后是IOC过程: IOC接口: 1.BeanFactory:IOC容器最基本的实现,一般开发不会使用,是Spring内部的使用接口 2.ApplicationContext:BeanFactory的子接口,

qq_42879463的博客 353
上一篇: Java数组
下一篇: spring boot常用的注解
与黑夜为伍
博客等级 码龄7年 19粉丝 80原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值