Spring框架优势

大家都知道使用spring框架可以由其管理对象(Bean),实现其控制反转的特点,这一大特点会为我们带来一下优势:

解耦

首先第一点优势就是解耦!
通过spring框架底层通过反射来创建对象而不是通过我们自己来new对象,很大程度上就已经降低了代码的耦合度.
耦合度就是对象之间的依赖关系,对象之间的依赖程度越高,维护成本也就越高,所以通过spring框架来管理对象而降低耦合度对我们的项目来说是很有益处的.

延迟加载

第二点优势就是延迟加载!
由spring管理对象,可以通过@Lazy注解标记,来使得对象的创建达到延迟加载的效果,只有在使用时才会打破延迟.

@Lazy可以用于描述类/方法
底层是通过value属性的true/false值,来表示是否延迟.
默认value属性为true,表示要延迟构建以及延迟初始化-->@Lazy(true)
如果写false,和没写该注解相同,表示不支持延迟-->@Lazy(false)

应用场景:
大对象(例如池对象),稀少用(容器初始化创建对象也用不到)
通常配合单例作用域使用

指定作用域

第三点优势就是可以指定作用域!
由spring管理对象,可以通过@Scope注解标记,指定类实例的作用域.

@Scope(" ")-" "中可以填入两个值:
singleton:单例作用域,类的实例在一个JVM内存中只有一份,spring负责创建负责销毁,还会存储到bean池中(默认)
prototype:多利作用域,类的实例何时需要何时创建,spring负责创建不负责销毁

一般可重用的对象设为单例;
一般不可重用对象或仅使用一次就不再使用对象设为多例.

描述生命周期

第四点优势就是可以描述生命周期!
由spring管理对象,可以通过@PostConstruct/@PreDestroy注解标记,来描述生命周期的初始化/销毁方法.

@PostConstruct此注解描述的方法为生命周期初始化方法,此方法会在对象构造方法之后执行,在这样的方法中一般会为创建好的对象再次进行一些初始化.
@PreDestroy此注解描述的方法为生命周期销毁方法,此方法会在对象销毁之前执行,在这样的方法中可以实现一些资源销毁操作.

实例如下:

@Scope
//@Scope("prototype")
@Lazy
@Component//将类交给spring管理
public class ObjectPool {
    public int size;
    public ObjectPool() {
        System.out.println("ObjectPool()");
    }
    @PostConstruct
    public void init() {
        System.out.println("init()");
    }
    @PreDestroy
    public void destiry() {
        System.out.println("destiry()");
    }
}
@SpringBootTest
public class ObjectPoolTests {
    @Autowired
    private ObjectPool objectPool1;
    @Autowired
    private ObjectPool objectPool2;
    @Test
    void testObjectPool() {
        System.out.println("objectPool1="+objectPool1);
        System.out.println(objectPool1==objectPool2);//比较对象地址
        objectPool1.size=10;
        System.out.println(objectPool2.size);
    }
}

以上代码实际运行后,可以观察其方法打印顺序,以及对象地址值的比较,继而验证上述注解的作用.

@Autowired依赖注入

从上面代码块中的实例里可以看到在测试类中是通过@Autowired注解标记的方式将对象作为属性注入到另一个类中的.这也是使用spring框架时常用到的一个方式.

@Autowired

@Autowired描述属性或方法时,系统底层会先根据描述属性或方法参数的类型去spring容器中进行查找:

当有且只有一个相同类型的对象时,会直接注入;
但若检测到多个类型都满足注入要求,还会根据@Autowired描述的属性或方法参数名查找是否有名字匹配的对象,若有会直接注入,没有则会抛出异常.

@Qualifier

如果我们有明确的要求,希望@Autowired注入的类型/名称都是指定类型/名字的对象,可以通过@Qualifier注解对其属性或参数进行描述.

@Qualifier注解必须配合@Autowired注解使用!

实例如下

@SpringBootTest
public class CacheTests {
    //描述属性
    @Autowired
    @Qualifier("weakCache")
    private Cache cache;

    @Test
    void testCache() {
        System.out.println("cache="+cache);
    }
}
@Component
public class SearchService {
    private Cache cache;
    
    //描述方法
    @Autowired
    public SearchService( @Qualifier("softCache") Cache cache) {
        this.cache=cache;
        System.out.println("SearchService.this.cache="+this.cache);
    }
}

迈克丝
82 声望5 粉丝

一步一步学技术,踏踏实实涨经验,兴趣广泛,广交好友,希望大家多多指正/批评.