1、Map依赖注入:
- @Autowired
- private Map<String, BaseService> map;
这样会注入:key是bean名字;value就是所有实现了BaseService的Bean,假设使用上一篇的例子,则会得到:
{organizationService=com.sishuok.spring4.service.OrganizationService@617029, userService=com.sishuok.spring4.service.UserService@10ac73b}
2、List/数组注入:
- @Autowired
- private List<BaseService> list;
这样会注入所有实现了BaseService的Bean;但是顺序是不确定的,如果我们想要按照某个顺序获取;在Spring4中可以使用@Order或实现Ordered接口来实现,如:
- @Order(value = 1)
- @Service
- public class UserService extends BaseService<User> {
- }
这种方式在一些需要多态的场景下是非常有用的。
3、@Lazy可以延迟依赖注入:
- @Lazy
- @Service
- public class UserService extends BaseService<User> {
- }
- @Lazy
- @Autowired
- private UserService userService;
我们可以把@Lazy放在@Autowired之上,即依赖注入也是延迟的;当我们调用userService时才会注入。即延迟依赖注入到使用时。同样适用于@Bean。
4、@Conditional
@Conditional类似于@Profile(一般用于如我们有开发环境、测试环境、正式机环境,为了方便切换不同的环境可以使用
@Profile指定各个环境的配置,然后通过某个配置来开启某一个环境,方便切换)
,但是@Conditional的优点是允许自己定义规则。可以指定在如@Component、@Bean、@Configuration等注解的类上,以绝对Bean是否创建等。首先来看看使用@Profile的用例,假设我们有个用户模块:
1、在测试/开发期间调用本机的模拟接口方便开发;
2、在部署到正式机时换成调用远程接口;
- public abstract class UserService extends BaseService<User> {
- }
- @Profile("local")
- @Service
- public class LocalUserService extends UserService {
- }
- @Profile("remote")
- @Service
- public class RemoteUserService extends UserService {
- }
我们在写测试用例时,可以指定我们使用哪个Profile:
- @ActiveProfiles("remote")
- @RunWith(SpringJUnit4ClassRunner.class)
- @ContextConfiguration(locations = "classpath:spring-config.xml")
- public class ServiceTest {
- @Autowired
- private UserService userService;
- }
这种方式非常简单。如果想自定义如@Profile之类的注解等,那么@Conditional就派上用场了;假设我们系统中有好多本地/远程接口,那么我们定义两个注解@Local和@Remote注解要比使用@Profile方便的多;如:
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.TYPE, ElementType.METHOD})
- @Conditional(CustomCondition.class)
- public @interface Local {
- }
- @Retention(RetentionPolicy.RUNTIME)
- @Target({ElementType.TYPE, ElementType.METHOD})
- @Conditional(CustomCondition.class)
- public @interface Remote {
- }
- public class CustomCondition implements Condition {
- @Override
- public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
- boolean isLocalBean = metadata.isAnnotated("com.sishuok.spring4.annotation.Local");
- boolean isRemoteBean = metadata.isAnnotated("com.sishuok.spring4.annotation.Remote");
- //如果bean没有注解@Local或@Remote,返回true,表示创建Bean
- if(!isLocalBean && !isRemoteBean) {
- return true;
- }
- boolean isLocalProfile = context.getEnvironment().acceptsProfiles("local");
- //如果profile=local 且 bean注解了@Local,则返回true 表示创建bean;
- if(isLocalProfile) {
- return isLocalBean;
- }
- //否则默认返回注解了@Remote或没有注解@Remote的Bean
- return isRemoteBean;
- }
- }
然后我们使用这两个注解分别注解我们的Service:
- @Local
- @Service
- public class LocalUserService extends UserService {
- }
- @Remote
- @Service
- public class RemoteUserService extends UserService {
- }
首先在@Local和@Remote注解上使用@Conditional(CustomCondition.class)指定条件,然后使用 @Local和@Remote注解我们的Service,这样当加载Service时,会先执行条件然后判断是否加载为Bean。@Profile就是这 样实现的,其Condition 是:org.springframework.context.annotation.ProfileCondition。可以去看下源码,很简单。
5、基于CGLIB的类代理不再要求类必须有空参构造器了:
这是一个很好的特性,使用构造器注入有很多好处,比如可以只在创建Bean时注入依赖,然后就不变了,如果使用setter注入,是允许别人改的。 当然我们可以使用spring的字段级别注入。如果大家使用过如Shiro,我们可能要对Controller加代理。如果是类级别代理,此时要求 Controller必须有空参构造器,有时候挺烦人的。spring如何实现的呢?其内联了objenesis类库,通过它来实现,可以去其官网看看介绍。这样就支持如下方式的构造器注入了:
- @Controller
- public class UserController {
- private UserService userService;
- @Autowired
- public UserController(UserService userService) {
- this.userService = userService;
- }
- }
org.springframework.cglib.proxy.Enhancer在其github和maven仓库中的source中竟然木有,其github:https://github.com/spring-projects/spring-framework/tree/master/spring-core/src/main/java/org/springframework/cglib;难道忘了吗?
相关推荐
《Spring技术内幕》学习笔记4——IoC容器解析Bean定义资源并注册解析后的Bean 《Spring技术内幕》学习笔记5——IoC容器的依赖注入 《Spring技术内幕》学习笔记6——IoC容器的高级特性 《Spring技术内幕》学习笔记7...
spring boot整合JPA——demo
NULL 博文链接:https://ylxy3058.iteye.com/blog/2225314
spring 2.5新特性spring 2.5新特性spring 2.5新特性spring 2.5新特性spring 2.5新特性
Spring4新特性(8)注解脚本任务MVC等其他特性改进Java开发Java经验技巧共7页.pdf.zip
Spring3事务管理——使用@Transactional 注解.rar
配置Spring的核心容器IOC
spring3.0的新特性 以及注解简化mvc让他真正解耦合
spring2.5新特性相关,我自己整理的
NULL 博文链接:https://ylxy3058.iteye.com/blog/2226323
精通Spring4.x企业应用开发实战pdf+源码,书和代码对的上呦
精通Spring+4.x++企业应用开发实战
这是一个详细介绍Spring3.0新特性的文档
从概念上讲:Spring 容器是 Spring框架的核心,是用来管理对象的。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。 从代码上讲:一个Spring容器就是某个实现了...
而控制反转就是把传统程序中需要实现对象的创建、代码的依赖,反转给一个专门的"第三方"即容器来实现,即将创建和查找依赖对象的控制权交给容器,由容器将对象进行组合注入,实现对象与对象的松耦合,便于功能的复用...
精通Spring+4.x++企业应用开发实战.pdf 个人收集电子书,仅用学习使用,不可用于商业用途,如有版权问题,请联系删除!
Spring框架资料,Ioc容器, AOP面向切面编程 ,声明式事务 ,Spring5新特性