Spring学习笔记之——Spring IoC 控制反转

Spring IoC 控制反转

内容参考《Spring5高级编程》。

IoC概述:

IoC概述:IoC意为控制反转。IoC的核心是DI,意为依赖注入。旨在提供一种更简单的机制设置依赖项,并在整个生命周期中去管理这些依赖项。
通常 IoC可以分解为两种子类型:依赖注入依赖查找
依赖查找:依赖拉取和上下文依赖查找
依赖注入:构造函数和setter依赖注入

依赖拉取

public static void main(String[] args){
     
    ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
    
    TestDao tt=ctx.getBean("test",TestDao.class);
    tt.sayhello();
}

构造函数依赖注入
public Constructorinjection (Dependency dependency)

public class Constructorinjection {
      
    private Dependency dependency; 
    public Constructorinjection (Dependency dependency) {
      
        this .dependency = dependency; 
    }
    @Override 
    publiC String toString () {
      return dependency.toString();}
}

setter依赖注入
public void setDependency(Dependency dependency)

public class Constructorinjection {
      
    private Dependency dependency; 
    public void setDependency(Dependency dependency) {
      
        this .dependency = dependency; 
    }
    @Override 
    publiC String toString () {
      return dependency.toString();}
}

区别:setter注入可以在没有依赖项的情况下创建对象,耦合度较低。

setter可以在接口上声明依赖项,但除配置参数等信息,不应定义。

以上为IoC的基本介绍

Spring中的DI容器实现

BeanFactory实现

public static void main(String[] args){
     
    // 初始化工厂对象
    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
    //初始化Bean读取器
    XmlBeanDefinitionReader rdr = new XmlBeanDefinitionReader(factory); 
    //加载XML实例
    rdr.loadBeanDefinitions(new ClassPathResource("spring/xml-bean-factory-config.xml");
    Oracle oracle=(Oracle)factory.getBean("oracle");
    System.out.println(oracle.defineMeaning());
}

ApplicationContext实现

设置Spring配置选项:可xml,java注解,也可混合使用。
XML:

<bean id="provider" class="com.project.provider"/>
<bean id="renderer" class="com.project.renderer"
    p:messageProvider-ref]"provider"/>

注解:

1. @Component("provider") //注解依赖项
2. @Service("renderer") //注解依赖对象
3. @Autowired //查找该类型的Bean并作为调用该方法的参数,该注解在依赖对象的构造方法或setter上。

其中注解形式须在XML中另加:

<context:component-scan base-package="com.apress.prospring5.ch3.annotation"/>

只要注解和XML写正确并没有冲突,单纯XML,注解或混合并不影响ApplicationContext实现依赖注入

代码如下:

public static void main(String[] args){
     

    GenericXmlApplicationContext ctx=new GenericXmlApplicationContext();
    ctx.load("classpath:spring/app-context-xml.xml");
    ctx.refresh();
    
    Oracle oracle=(Oracle)ctx.getBean("oracle");
    System.out.println(oracle.defineMeaning());
    ctx.close();
}

Java配置实现

使用一个配置类来代替以上的application.xml

1. @Configuration //注解在配置类类名上 
2. @Bean //注解在创建的方法上,可获取Prodiver,rendder实例

配置类略,使用如下:

public static void main(String[] args){
     
    //初始化并加载配置类
    ApplicationContext ctx = new AnnotationfigApplicationContext(
    HelloWorldConfigurationContext.class);
    
    Oracle oracle=(Oracle)ctx.getBean("oracle");
    System.out.println(oracle.defineMeaning());
}
<context:component-scan base-package="com.apress.prospring5.ch3.annotation"/>
+ XML
// 等效于:
@ComponentScan(basePackages={
     "com.apress.prospring5.ch3.annotation"})
@Configuration
+ 配置类

使用setter或构造函数实现的XML中bean配置

  1. setter
<bean id="provider" class="com.project.provider"/>
<bean id="renderer" class="com.project.renderer">
    <property name="provider" ref="provider">
    //name:为属性
</bean>

//新版本
<bean id="provider" class="com.project.provider"/>
<bean id="renderer" class="com.project.renderer"
    p:messageProvider-ref="provider"/>

//注解
@Autowired
+ settter方法


  1. 构造函数
<bean id="provider" class="com.project.provider">
    <constructor-arg index=0 value="i hope"/>
<bean>

// 新版本
<bean id="provider" class="com.project.provider"
    c:message="i hope"/>
    // c:_0="i hope"/> 构造函数参数索引
//注解
@Autowired
+ 构造函数

  1. 字段注入

通过@Autowired注解来注解类成员,依赖项直接注入字段中,不需构造函数和setter。(其中遇到的类成员为私有问题可通过反射解决)

一般不推荐使用

@Autowired
+ 类成员
  1. SpEL(Spring Expression Language)
@Component("injectSimpleConfig") //与类名一致?

<!--private String name = "HGF";-->
<!--private int age = 39;-->

// injectSimpleConfig 配置在xml中
<bean id="injectSimpleConfig" class="com.apress.prospring5.ch3.xml.InjectSimpleConfig"/>

<bean id="injectSimpleSpel" class="com.apress.prospring5.ch3.xml.InjectSimpleSpel"
    p:name="#{injectSimpleConfig.name}"
    p:age="#{
     injectSimpleConfig.age+1}/>

<!--name = "HGF";-->
<!--age = 40;-->

一般情况下,@Service 与 @Component 并无差别,@Service是@Component 的一个特例。表明注解放入类正在项应用程序中的其他层提供业务服务。

实现将一个bean注入另一个bean

依赖对象定义的setter方法,比如是setOracle(),被注入的bean类型不一定是定义的确切类型。如果是接口,被注入的bean类型必须实现该接口。如果声明的是一个类,必须是相同的类型或者是子类型。

<bean id="oracle" name="wiseworm" class="...BookwormOracle"/>

<bean id="injectRef" class="...">
    <property name="oracle">
        <ref bean="oracle"/>
        // 
    </property>
</bean>

你可能感兴趣的:(Spring学习笔记,Spring)