python做网站后台,新人做网络咨询的网站,中国住房和城乡建设部网站官网,全屋设计1 概述 本篇主要介绍使用依赖注入的一些实战经验。
2 把握Bean的作用域 前面说到Setter方法注入时#xff0c;提到了Spring中的Bean作用域的概念。作用域描述了Bean在Spring IoC容器上下文中的生命周期和可见性。现在讨论Spring框架中不同类型的Bean作用域及其在使用上的指导…1 概述 本篇主要介绍使用依赖注入的一些实战经验。
2 把握Bean的作用域 前面说到Setter方法注入时提到了Spring中的Bean作用域的概念。作用域描述了Bean在Spring IoC容器上下文中的生命周期和可见性。现在讨论Spring框架中不同类型的Bean作用域及其在使用上的指导规则。 如果想要通过注解来设置Bean的作用域可以使用下面示例代码
Configuration
public class Appcofig {BeanScope(singleton)public HealthRecordService createHealthRecordService(){return new HealthRecordServiceImpl();}
}public interface HealthRecordService {
}
public class HealthRecordServiceImpl implements HealthRecordService{
}可以看到这里使用了一个Scope注解来指定Bean的作用域为单例的singleton。在Spring中除了单例作用域之外还有一个prototype即原型作用域也可成为多例作用域与单例作用域进行区分。使用方式上同样可以使用下列代码进行设置。
Configuration
public class Appcofig1 {BeanScope(value ConfigurableBeanFactory.SCOPE_SINGLETON)Scope(value ConfigurableBeanFactory.SCOPE_PROTOTYPE)public HealthRecordService createHealthRecordService(){return new HealthRecordServiceImpl();}
} 在SpringIoC容器中Bean的默认作用域是单例也就是不管有多少个对Bean的引用容器只会创建一个实例。而原型作用域则不同每次请求Bean时Spring IoC容器都会创建一个新的对象实例。 从两种作用域的效果而言总结出一条开发上的经验即对于有状态的Bean应该使用原型作用域反之则使用单例作用域。 那么什么样的Bean是有状态的呢结合Web应用程序可以明确对于每次HTTP请求而言都应该创建一个Bean来代表这一次的请求对象。同样对于会话而言也需要针对每个会话创建一个会话状态对象。这些都是创建的有状态的Bean。为了更好地管理这些Bean的生命周期Spring还专门针对Web开发场景提供了对应的request和session作用域。
3 灵活使用注解配置 在使用Spring依赖注入类型时通常可以使用XML配置、Java代码配置以及注解配置这三种方式。随着Spring Boot框架的流程使用注解配置已经成为目前最主流的开发方法。除了前面已经给出的最常见的Autowired注解Spring Boot框架还提供了一组非常有用的注解帮助我们更好的管理所注入的对象包括Primary注解和Qualifier注解。 在Spring IoC容器中针对HealthRecordService这样一种接口类型原则上容器只允许注入一个实现类。如果存在该类型的多个对象实例那么容器就会NoUniqueBeanDefinitionException意味着容器无法决定选择哪一个实例来进行注入。这时候就可以使用Primary注解来帮助容器做出选择该注解的使用方式如下
Component
public class HealthRecordServiceImplA implements HealthRecordService{
}
Component
Primary
public class HealthRecordServiceImplB implements HealthRecordService{
} 这时候Spring IoC容器只会注入HealthRecordServiceImplB这个实例类这在管理针对某种类型的多个实例时非常有效。 和Primary注解的应用场景类似Qualifier注解为我们选择实例类进行注入提供了更加灵活的实现方式代码如下
Component
Qualifier(healthRecordServiceImplA)
public class HealthRecordServiceImplA implements HealthRecordService{
}
Component
Qualifier(healthRecordServiceImplB)
public class HealthRecordServiceImplB implements HealthRecordService{
} 可以看到这里对不同的实现类通过Qualifier注解设置了不同的名称这样在使用时就可以通过该名称获取不同的实例代码如下
public class HealthRecordServiceImplA implements HealthRecordService{AutowiredQualifier(healthRecotdServiceA)private HealthRecordService healthRecordService;
}
4 设置组件扫描范围 在Spring中可以通过设置组件扫描范围来简化Bean的注入配置。因为任何类都位于某一个包接口之下所以Spring提供了一个ComponentScan注解该注解在需要大规模对象注入的场景下非常有用代码如下
Configuration
ComponentScan(basePackages com.jay)
public class Appcofig2 {
} 在这个示例中Spring会扫描由basePackages指定的包路径com.jay及其子路径下的所有Bean并把它们注入到容器中当前首先需要再这些类上添加Component注解以及由该注解衍生的Service、Pepository、Controler等注解。
5 不同配置的性能分析 首先要讨论的是前面介绍的ComponentScan注解。因为该注解会扫描basePackages指定的包中的所有组件所以如果指定包中的组件并不需要在应用程序启动时就全部加载到容器中。那么对包路径进行精细化设计是一个实践技巧。例如可以通过设置一个列表来细化具体的包结构路径。代码如下
Configuration
ComponentScan(basePackages com.jay.controller,com.jay.service)
public class Appcofig2 {
} 然后要讨论的是单例模式和原型模式对性能的影响。在Spring中当把Bean范围设置为prototype每次请求Bean时Spring IoC容器都会创建一个新的对象实例。所以使用原型模式在创建过程中会对性能产生影响对那些初始化过程需要消耗巨大资源的对象而言尤其如此这些对象常见的有网络连接对象、数据库连接对象等。因此对这些对象应该避免使用原型模式。或者应该在使用前仔细设计并对性能进行充分测试。 最后一个值得讨论的性能分析点在于Spring IoC容器的延迟加载Lazy Loading和预加载Preloading机制。通过Autowired注入的Bean都是在Spring IoC容器启动时被创建和初始化的这个过程被称为预加载。但有时候希望能够延迟Bean的加载时机这时候就可以使用Lay注解,示例如下
Component
Lazy
public class HealthRecordServiceImpl implements HealthRecordService{
}添加了Lazy注解的效果是只有在使用到这个Bean时它才会去初始化而不是在Spring IoC容器启动时直接初始化这样就可以节省容器资源。 延迟加载确保在请求时动态加载Bean预加载确保在使用Bean之前加载Bean。Spring IoC容器默认使用预加载。然后在容器启动时就加载所有类并不是一个明智的决定因为有些Bean实例会非常消耗资源。应该根据实际情况选择具体的加载方法。