目录
- 概述
- 使用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关系如下图所示:
使用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关系如下图所示:
显然这样各类之间的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关系如下图所示:
很显然,这几个类之间的dependencies关系简单清晰很多。
总结
使用spring来完成对对象的创建工作,可以很大的简化各类之间的依赖关系,从而实现高类聚低耦合。
需要注意的是,spring容器只会对@Component注解的类创建一个对象,即如果在Main类中使用两次Car car = context.getBean(“car”,Car.class);获取的是同一个对象。