Spring中Bean的注入方式

SpringIoc的理解

  • IOC就是控制反转,是指创建对象的控制权的转移,以前创建对象的主动权和时机是由自己把控的,而现在这种权利转移到了spring容器中,并由容器根据配置文件去创建实例和管理各个实例之间的依赖管理,对象与对象之间的松散耦合,也利于功能的复用。
  • DI依赖注入是控制反转同一个概念的不同角度的描述,即应用程序在运行时依赖IOC容器来动态注入对象需要的外部资源
  • 简述 IOC容器让对象的创建不用去new了 而是由spring依赖注入自动生产,使用java反射机制,根据配置文件在运行时动态去创建对象以及管理对象,并调用对象方法。

基于XML进行IOC配置

通过Set()方法注入

这是最简单的注入方式,假设有一个SpringAction,类中需要实例化一个SpringDao对象,那么就可以定义一个private的SpringDao成员变量,然后创建SpringDao的set方法(这是ioc的注入入口)

package com.yun.springdemo.action; 
public class SpringAction { 
    //注入对象springDao 
    private SpringDao springDao; 
    //一定要写被注入对象的set方法 
    public void setSpringDao(SpringDao springDao) { 
    this.springDao = springDao; 
} 
 
public void ok(){ 
    springDao.ok(); 
} 
}

随后编写spring的xml文件中,name属性是class属性的一个别名,class属性指类的全名,因为在SpringAction中有一个公共属性Springdao,所以要在标签中创建一个标签指定SpringDao。标签中的name就是SpringAction类中的SpringDao属性名,ref指下面,这样其实是spring将SpringDaoImpl对象实例化并且调用SpringAction的setSpringDao方法将SpringDao注入:

<!--配置bean,配置后该类由spring管理--> 
<bean name="springAction" class="com.yun.springdemo.action.SpringAction"> 
<!--(1)依赖注入,配置当前类中相应的属性--> 
<property name="springDao" ref="springDao"></property> 
</bean> 
<bean name="springDao" class="com.yun.springdemo.dao.impl.SpringDaoImpl"></bean>

通过构造器注入

这种方式的注入是指带有参数的构造函数注入,看下面的例子,创建了两个成员变量SpringDao和User,但是并未设置对象的set方法,所以就不能支持第一种注入方式,这里的注入方式是在SpringAction的构造函数中注入,也就是说在创建SpringAction对象时要将SpringDao和User两个参数值传进来:


public class SpringAction { 
    //注入对象springDao 
    private SpringDao springDao; 
    private User user; 
 
    public SpringAction(SpringDao springDao,User user){ 
    this.springDao = springDao; 
    this.user = user; 
    System.out.println("构造方法调用springDao和user"); 
} 
 
public void save(){ 
    user.setName("yun"); 
    springDao.save(user); 
} 

在XML文件中同样不用的形式,而是使用标签,ref属性同样指向其它标签的name属性:

<!--配置bean,配置后该类由spring管理--> 
<bean name="springAction" class="com.yun.springdemo.action.SpringAction"> 
<!--(2)创建构造器注入,如果主类有带参的构造方法则需添加此配置--> 
<constructor-arg ref="springDao"></constructor-arg> 
<constructor-arg ref="user"></constructor-arg> 
</bean> 
<bean name="springDao" class="com.yun.springdemo.dao.impl.SpringDaoImpl"></bean> 
<bean name="user" class="com.yun.springdemo.vo.User"></bean>

解决构造方法参数的不确定性:你可能会遇到构造方法传入的两参数都是同类型的,为了分清哪个该赋对应值,则需要进行一些小处理:

下面是设置index,就是参数位置:

<bean name="springAction" class="com.yun.springdemo.action.SpringAction"> 
<constructor-arg index="0" ref="springDao"></constructor-arg> 
<constructor-arg index="1" ref="user"></constructor-arg> 
</bean> 

另一种是设置参数类型:

<constructor-arg type="java.lang.String" ref=""/>

通过静态工厂方法注入

静态工厂顾名思义,就是通过调用静态工厂的方法来获取自己需要的对象,

public class DaoFactory { 
//静态工厂 
public static final FactoryDao getStaticFactoryDaoImpl(){ 
    return new StaticFacotryDaoImpl(); 
    } 
}

关键类,这里我需要注入一个FactoryDao对象,看起来跟第一种注入一模一样,但是xml配置会发现有很大差别:

public class SpringAction { 
//注入对象 
private FactoryDao staticFactoryDao; 
 
public void staticFactoryOk(){ 
    staticFactoryDao.saveFactory(); 
} 
//注入对象的set方法 
public void setStaticFactoryDao(FactoryDao staticFactoryDao) { 
    this.staticFactoryDao = staticFactoryDao; 
} 
}

Spring的IOC配置文件,注意看指向的class并不是FactoryDao的实现类,而是指向静态工厂DaoFactory,并且配置 factory-method=”getStaticFactoryDaoImpl”指定调用哪个工厂方法:

<!--配置bean,配置后该类由spring管理--> 
<bean name="springAction" class="com.bless.springdemo.action.SpringAction" > 
<!--(3)使用静态工厂的方法注入对象,对应下面的配置文件(3)--> 
<property name="staticFactoryDao" ref="staticFactoryDao"></property> 
</property> 
</bean> 
<!--(3)此处获取对象的方式是从工厂类中获取静态方法--> 
<bean name="staticFactoryDao" class="com.bless.springdemo.factory.DaoFactory" factory-method="getStaticFactoryDaoImpl"></bean> 

通过实例工厂方法注入

实例工厂的意思是获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法:

public class DaoFactory { 
//实例工厂中获取对象不是静态方法 
public FactoryDao getFactoryDaoImpl(){ 
    return new FactoryDaoImpl(); 
} 
}
public class SpringAction { 
//注入对象 
private FactoryDao factoryDao; 
 
public void factoryOk(){ 
    factoryDao.saveFactory(); 
} 
 
public void setFactoryDao(FactoryDao factoryDao) { 
    this.factoryDao = factoryDao; 
    } 
} 

在创建FactoryDao对象前,需要先实例化工厂类,看下图的xml配置

<!--配置bean,配置后该类由spring管理--> 
<bean name="springAction" class="com.bless.springdemo.action.SpringAction"> 
<!--(4)使用实例工厂的方法注入对象,对应下面的配置文件(4)--> 
<property name="factoryDao" ref="factoryDao"></property> 
</bean> 
 
<!--(4)此处获取对象的方式是从工厂类中获取实例方法--> 
<bean name="daoFactory" class="com.bless.springdemo.factory.DaoFactory"></bean> 
<bean name="factoryDao" factory-bean="daoFactory" factory-method="getFactoryDaoImpl"></bean> 

静态工厂和实例化工厂的区别

  • Spring使用静态工厂方法来创建Bean实例时,Spring将先解析配置文件,并根据配置文件指定的信息,通过反射调用静态工厂类的静态工厂方法,并将该静态工厂方法的返回值作为Bean实例,在这个过程中,Spring不再负责创建Bean实例,Bean实例是由用户提供的静态工厂方法提供的。(xml中配置一个bean)

  • 实例工厂方法又称为工厂方法模式:先创建工厂实例,然后通过工厂实例来调用创建实例对象的方法进行对象的初始化。xml中需要配置两个bean,一个是工厂对象,一个是factoryDao对象(是通过工厂对象中的创建实例对象方法来获取的)

通过注解方式

使用@Component+@ComponentScan

  • 使用@ComponentScan注解来扫描声明了@Controller、@Service、@Component注解的类
    开发中常用的 @Service和 @Controller 都是 @Component下的注解 ,

为什么平时却没用@ComponentScan注解呢?

因为平时用的都是Springboot,Springboot启动类上的 @SpringbootApplication 注解类下已经带有 @ComponentScan 注解了,默认扫描启动类同级包下的@Component

@Configuration+@Bean

当我们需要引入第三方的 jar 包时,可以用 @Bean 注解来标注,同时需要搭配 @Configuration 来使用。

  1. @Configuration 用来声明一个配置类,可以理解为 xml 的 标签
  2. @Bean 用来声明一个 bean,将其加入到 Spring 容器中,可以理解为 xml 的 标签
    简单样例:将 RedisTemplate 注入 Spring
@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        ......
        return redisTemplate;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值