乐趣区

关于java:Spring框架优势以及Autowired依赖注入过程

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);
    }
}
退出移动版