美文网首页程序员
(101)Spring 之 IOC及其容器

(101)Spring 之 IOC及其容器

作者: 林湾村龙猫 | 来源:发表于2017-12-11 21:31 被阅读174次

概述

Spring的最终目的是简化应用开发。spring用于替代更加重量级的企业级java技术,如EJB(Enterprise JavaBean)。

为了降低Java开发的复杂度。spring采取了以下4中关键策略:

  • 基于POJO(Plain Ordinary Java Objects,实际上就是普通的java类)的轻量级和最小侵入式编程。
  • 通过依赖注入(DI, Dependency Injection)和面向接口编程实现松耦合。
  • 基于切面(AOP, Aspect Oriented Programming)和惯例(可以理解为默认配置、方式)进行声明式编程。
  • 通过切面和模板减少重复代码。
ioc容器及其使用

他山之石

IOC容器存在价值及具象化

我们通过租房来具象化说明什么是IOC (Inversion of Control,控制反转)。

没有中介之前,我们是这么找房子的:


传统找房子

我们需要,一个个去找每一个房子。如果找到合适的房子(比如房子3),我们还得自己取找房东、找房产局。如果我们满意的房子(比如 房子1),我们还得取找二房东。多累啊,我们不就是想找个房子住么,管他几房东。所以就有了房产中介。

现代找房子

这下舒服多了。租房流程,就变成了,我把我找房子的需求提给中介,中介找到合适的房子给我。

这里,我们可以简单的对IOC与DI做个定义,以方便记忆和理解:

  • 开发者:我
  • 类:房子类型、房屋拥有者类型
  • Bean对象:房子、房东、房产局等等
  • IOC容器:房屋中介
  • IOC(Inversion Of Control 控制反转): 把找房子的权利(控制)交给中介(不是自己,所以叫反转)过程
  • DI(Dependency Injection 依赖注入):把找好合适的房子(依赖,中介已经处理了相关杂事)交给我的过程

Java是一门面向对象编程语言。Java应用本质上是若干对象其依赖关系的组合。

一句话,在java中,将对象的创建与对象的使用分离开,通过依赖注入(DI)的方式达到对象控制反转(IOC)的目的。原本需要自己做创建对象、维护各个对象关系,现在统一交给统一专业的人或服务处理。

创建对象等操作就是你对对象的控制权,把控制权交给三方,这就是 控制反转(IOC) 的意思。

当需要某个对象的时候,三方将合适的对象给你,这个就是 依赖注入(DI) 的意思。

IOC具象化

关系

主要类或接口uml图

IOC容器接口设计图

ApplicationContext 扩展了BeanFactory后的结果,BeanFactory为bean对象的出生地。

BeanDefinition载入

定义一个bean对象长什么样子,在spring中叫BeanDefinition。如何初始化一个BeanDefinition,spring中常用三种方式定义:xml文件、注解扫描、java代码.

加载BeanDefinition

bean的生命周期

spring中bean生命周期.png

Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:

  • Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法。
  • Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean这些接口的方法
  • 容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。
  • 工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器  接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

举例(通过注解与java代码定义bean)

  • 定义一个Animal接口。
  • 定义实现Animal接口的两个动物Cat,Dog类;
  • 定义一个接口代理AnimalProxy。
  • 定义一个spring Bean java类

实现通过代理类完成不同操作。

1.Animal接口

package bean;

public interface Animal {

    public void sayName();
}

2.Cat类

package bean;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Primary
@Component
public class Cat implements Animal {

    public void sayName() {
        System.out.println("this is cat");
    }
}

3.Dog类

package bean;

import org.springframework.stereotype.Component;

@Component
public class Dog implements Animal {
    public void sayName() {
        System.out.println("this is dog");
    }
}

4.AnimalProxy类

package bean;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class AnimalProxy implements Animal {

    @Autowired
    private Animal animal;

    public void sayName(){
        animal.sayName();
    }
}

5. AnimalConfig(Bean定义类)

package bean;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * User: Rudy Tan
 * Date: 2017/11/24
 */
@Configuration
@ComponentScan
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AnimalConfig {
}

6.测试类:

import bean.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AnimalConfig.class)
public class AppTest {

    @Autowired
    private AnimalProxy animalProxy;

    @Test
    public void testBeanLoad(){
        animalProxy.sayName();
    }
}

说明:

  • 注解Component:指明该类为bean类
  • 注解Primary:指明当多个bean对象满足获取条件时候,该对象优选获取。
  • 注解Configuration:指明该类为spring bean定义类。
  • 注解ComponentScan:开启当前目录下的bean注解扫描。
  • 注解EnableAspectJAutoProxy:启用aspectJauto代理。
  • 注解Autowired:该属性,spring自动载入。

总结,多人个人或多个类协助处理问题或实现某个功能,总得要找个领头的来管理这些关系吧。

都看到这里了,成神之路上,要不要一起?


微信公众号rudy_tan_home

相关文章

网友评论

    本文标题:(101)Spring 之 IOC及其容器

    本文链接:https://www.haomeiwen.com/subject/xgjwixtx.html