Spring框架概述 --- 控制反转, 依赖注入, 容器和Bean

Spring框架的好处

  • 轻量: Sprinh是轻量的, 基础版本大约2MB
  • 控制反转: Spring 通过控制反转实现了松散耦合
  • AOP: Spring支持面向切面的编程
  • MVC容器: Spring的Web框架
  • 事务管理: Spring提供一个持续的事务管理接口, 可以拓展到上至本地事务下至全局事务
  • 异常处理: Spring提供方便的API把具体技术的相关异常转化为一致的unchecked异常

控制反转

  • 一种设计思想,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制
  • 具体来说: 在传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;
  • 传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;
    因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了

Spring IOC容器和Bean

  • Bean是Spring管理的基本单位,在基于Spring的Java EE应用中,所有的组件都被当成Bean处理,包括数据源、Hibernate的SessionFactory、事务管理器等。在Spring中,Bean的是一个非常广义的概念,任何的Java对象、Java组件都被当成Bean处理。
  • Spring框架的核心是Spring IOC容器. 容器创建对象, 将它们装配在一起, 配置它们并管理生命周期.

BeanFactory

  • BeanFactory是ApplicationContext 的父类, BeanFactory实际上可以说是Spring的核心容器
  • 这是一个用来访问 Spring 容器的 root 接口,要访问 Spring 容器,我们将使用 Spring 依赖注入功能,使用 BeanFactory 接口和它的子接口。
  • 通常情况,BeanFactory 的实现是使用懒加载的方式,这意味着 beans 只有在我们通过 getBean() 方法直接调用它们时才进行实例化。

ApplicationContext

  • ApplicationContext 是 Spring 应用程序中的中央接口,用于向应用程序提供配置信息。它继承了 BeanFactory 接口,所以 ApplicationContext 包含 BeanFactory 的所有功能以及更多功能!它的主要功能是支持大型的业务应用的创建。
  • 与 BeanFactory 懒加载的方式不同,它是预加载,所以,每一个 bean 都在 ApplicationContext 启动之后实例化。

Bean的作用域

  • singleton: 单例模式, 在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例
  • protoype: 原型模式, 每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例
  • request: 对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,即每次HTTP请求将会产生不同的Bean实例。只有在Web应用中使用Spring时,该作用域才有效
  • session: 对于每次HTTP Session,使用session定义的Bean豆浆产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效
  • globalseesion: 每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效

在Spring中设置bean的作用域

  • 采用XML配置方式时,可以用标签中的scope属性可以指定bean的作用范围
<bean id="ajaxGetWarningDataAction" class="com.mln.pems.collect.actions.AjaxGetWarningDataAction" scope="prototype">
	<property name="daoSrv" ref="daoSrv" />
	<property name="emRunSrv" ref="emRunSrv" />
</bean>
  • 采用注解方式时,可以用@Scope(value = “singleton”)来指定
@Scope(value = “prototype”) 
public class AccountServiceImpl implements AccountService {
	......
}

依赖注入 — 控制反转的实现方法

  • Class A中用到了Class B的对象b,一般情况下,需要在A的代码中显式的new一个B的对象。采用依赖注入技术之后,A的代码只需要定义一个私有的B对象,不需要直接new来获得这个对象,而是通过相关的容器控制程序来将B对象在外部new出来并注入到A类里的引用中

依赖注入的三种方式 — 以下使用注解@Autowire的装配方法

  • 属性注入 – Attributed-based DI
@Service
public class BService {
	@Autowired
	AService aService;
}
  • setter注入 – setter-based DI
@Service
public class BService {
	AService aService;
	@Autowired
	public void setaService(AService aService) {
		this.aService = asService;
	}
}
  • 构造方法注入 – constructor-based DI
@Service
public class BService {
	AService aService;
	@Autowired
	public BService(AService aService) {
		this.aService = asService;
	}
}

setter注入和构造器注入的区别

  • 部分依赖:假设一个类中有3个属性,有一个有三个arg的构造函数和三个setter方法。在这种情况下,如果您只想传递一个属性的信息,则只能通过setter方法
  • 覆盖:Setter注入会覆盖构造函数注入。如果我们同时使用构造函数和setter注入,IOC容器将使用setter注入。
  • 变化:我们可以通过二次注射轻松更改值。它不会像构造函数一样创建新的bean实例。因此,setter注入比构造函数注入更灵活。

推荐使用构造器注入

  • 依赖不可变:这个好理解,通过构造方法注入依赖,在对象创建的时候就要注入依赖,一旦对象创建成功,以后就只能使用注入的依赖而无法修改了,这就是依赖不可变(通过 set 方法注入将来还能通过 set 方法修改)。
  • 依赖不为空:通过构造方法注入的时候,会自动检查注入的对象是否为空,如果为空,则注入失败;如果不为空,才会注入成功。
  • 完全初始化:由于获取到了依赖对象(这个依赖对象是初始化之后的),并且调用了要初始化组件的构造方法,因此最终拿到的就是完全初始化的对象了。

Spring中bean的装配 ---- 定义bean并描述bean之间的依赖关系

基于XML形式的手动装配

  • 手动装配,通常在XML配置文件中实现
//创建实体类: People
package com.lisi.pojo;
 
public class People {
    
    private Cat cat;
    private Dog dog;
    private String name;
	....
	....
}
手动装配
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
 
   <bean id="dog" class="com.lisi.pojo.Dog"/>
   <bean id="cat" class="com.lisi.pojo.Cat"/>
 
   <bean id="people" class="com.lisi.pojo.People">
       <property name="cat" ref="cat"/>
       <property name="dog" ref="dog"/>
       <property name="name" value="haha"/>
   </bean>
</beans>

基于XML形式的自动装配

//创建实体类: People
package com.lisi.pojo;
 
public class People {
    
    private Cat cat;
    private Dog dog;
    private String name;
	....
	....
}
  • byName: bean的id与属性名,一致则能赋值
<bean id="cat" class="com.lisi.pojo.Cat"></bean>
<bean id="dog" class="com.lisi.pojo.Dog"></bean>
<bean id="people" class="com.lisi.pojo.People" autowire="byName"></bean>
  • byType: 根据类型判断是否能装配,
  • spring容器中bean的类型为兼容性的属性赋值, 兼容性:父类与实现的接口可以
  • 使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常
  • 也就是不能再加入 <bean id="cat1" class="com.lisi.pojo.Cat"></bean>, 这样有两个Cat对象
<bean id="cat" class="com.lisi.pojo.Cat"></bean>
<bean id="dog" class="com.lisi.pojo.Dog"></bean>
<bean id="people" class="com.lisi.pojo.People" autowire="byType"></bean>

基于注解形式的自动装配

Spring 提供了以下多个注解,这些注解可以直接标注在 Java 类上,将它们定义成 Spring Bean

  • @Component:
  • 该注解用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等. 使用时只需将该注解标注在相应类上即可。
  • @Repository: 该注解用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
  • @Service: 该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
  • @Controller : 该注解通常作用在控制层(如 Struts2 的 Action、SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同

可以通过以下注解将定义好 Bean 装配到其它的 Bean 中

  • @Autowired:
  • 可以应用到 Bean 的属性变量、setter 方法、非 setter 方法及构造函数等,默认按照 Bean 的类型进行装配
  • @Autowired 注解默认按照 Bean 的类型进行装配,默认情况下它要求依赖对象必须存在,如果允许 null 值,可以设置它的 required 属性为 false。如果我们想使用按照名称(byName)来装配,可以结合 @Qualifier 注解一起使用
  • @Resource:
  • 作用与 Autowired 相同,区别在于 @Autowired 默认按照 Bean 类型装配,而 @Resource 默认按照 Bean 的名称进行装配。
  • @Resource 中有两个重要属性:name 和 type。
    Spring 将 name 属性解析为 Bean 的实例名称,type 属性解析为 Bean 的实例类型。
    如果指定 name 属性,则按实例名称进行装配;
    如果指定 type 属性,则按 Bean 类型进行装配;
    如果都不指定,则先按 Bean 实例名称装配,如果不能匹配,则再按照 Bean 类型进行装配;如果都无法匹配,则抛出 NoSuchBeanDefinitionException 异常。
  • @Qualifier 与 @Autowired 注解配合使用,会将默认的按 Bean 类型装配修改为按 Bean 的实例名称装配,Bean 的实例名称由 @Qualifier 注解的参数指定。
@Service
public class CategoryService {

    private static final Logger LOG = LoggerFactory.getLogger(CategoryService.class);

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private SnowFlake snowFlake;
    .....
    .....
	.....

基于Java配置类的装配

  • 不使用xml文件配置Bean,而是单独写一个配置类来配置Bean
  • @Bean 注解扮演与 元素相同的角色。用到方法上,表示当前方法的返回值是一个bean
  • @Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 Bean 间依赖关系。相当于spring的配置文件XML
@Configuration
public class ServiceConfiguration {
	 @Bean
	 public InventoryService inventoryService() {
	 	return new InventoryService();
	 }
	 @Bean
	 public ProductService productService() {
	 	return new ProductService(inventoryService());
	 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值