目录

  • 概述
  • 使用new创建对象
  • 使用反射创建对象
  • 使用spring容器创建对象
  • 总结


概述

在软件工程中,判断软件设计好坏的标准,主要看类的内聚性是否高,耦合度是否低,即经常讲到的高类聚低耦合,目的是使程序模块的可重用性、移植性大大增强。 通常程序结构中各模块的内聚程度越高,模块间的耦合程度就越低。
spring的一大核心作用就是解耦合,主要通过IOC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入)来实现,将创建bean对象的责任交给spring容器,从而实现解耦合的功能。

通过一个例子来理解spring的解耦合。
现在假设有三个类Car、Brake、和Enginee,很显然Car拥有Brake和Enginee,那么将会作为成员变量存在Car中。

public class Car {

    private Brake brake;

    private Enginee enginee;

    public Car(Brake brake,Enginee enginee){
        this.brake = brake;
        this.enginee = enginee;
    }
}

使用new创建对象

在使用到Car类的主类main中,要创建一个Car类对象,就要先创建它的成员变量Brake和Enginee对象

public class Main {
    public static void main(String[] args) {
        Brake brake = new Brake();
        Enginee enginee = new Enginee();

        Car car = new Car(brake,enginee);
    }
}

此时类图中的dependencies关系如下图所示:

java解耦合是什么意思 spring解耦是什么意思_java解耦合是什么意思


使用new来创建对象,其中创建Brake类和Enginee对象的责任全交给Main类,使得需要使用Car的Main类,还需要自己去创建其所需要的成员变量才能使用,这样对于Car类的使用会显得很复杂。

使用反射创建对象

当然,我们也可以使用java反射来创建对象,这样就会将创建Car类对象所需要的成员变量的工作交给了JVM,也就是需要使用Car类的Main类,不需要自己去创建Brake类和Enginee类对象了。

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        Brake brake = (Brake) Class.forName("Brake").newInstance();
        Enginee enginee = (Enginee) Class.forName("Enginee").newInstance();
        
        Car car = new Car(brake,enginee);
    }
}

在这种情况下,类图中的dependencies关系如下图所示:

java解耦合是什么意思 spring解耦是什么意思_创建对象_02


显然这样各类之间的dependencies关系简单清晰了一点,但是使用反射可能出现ClassNotFoundException, IllegalAccessException, InstantiationException异常,处理异常也是需要考虑的。

使用spring容器创建对象

使用spring容器创建对象,则每个类上方都加@Component注解,spring会自动扫描并创建同名对象。
此时的Car类只需:

@Component
public class Car {

    @Autowired
    private Brake brake;

    @Autowired
    private Enginee enginee;

}

Brake类和Enginee类都加上了@Component注解,使用@Autowired注解会自动从spring容器找到创建的brake,enginee对象,将其赋予Car的成员变量。

public class Main {

    public static void main(String[] args) {
        //这是一种获取ApplicationContext的方法,也可以使用其他方法获取ApplicationContext对象
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Car car = context.getBean("car",Car.class);
    }
}

在需要使用Car类对象的Main中,我们也只需要通过ApplicationContext去获取bean对象即可。这样就将创建对象的工作交给了spring,我们只需要告诉spring我们需要什么对象,即可随时获取到这个对象。

此时类图中的dependencies关系如下图所示:

java解耦合是什么意思 spring解耦是什么意思_创建对象_03


很显然,这几个类之间的dependencies关系简单清晰很多。

总结

使用spring来完成对对象的创建工作,可以很大的简化各类之间的依赖关系,从而实现高类聚低耦合。
需要注意的是,spring容器只会对@Component注解的类创建一个对象,即如果在Main类中使用两次Car car = context.getBean(“car”,Car.class);获取的是同一个对象。