`
jinnianshilongnian
  • 浏览: 21504047 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2418680
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:3008780
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5639490
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:259916
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1597317
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:250219
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5858951
Group-logo
跟我学Nginx+Lua开...
浏览量:702004
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:785224
社区版块
存档分类
最新评论

Spring4新特性——核心容器的其他改进

阅读更多

Spring4新特性——泛型限定式依赖注入

Spring4新特性——核心容器的其他改进

Spring4新特性——Web开发的增强

Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC 

Spring4新特性——Groovy Bean定义DSL

Spring4新特性——更好的Java泛型操作API 

Spring4新特性——JSR310日期API的支持

Spring4新特性——注解、脚本、任务、MVC等其他特性改进 

 

 

接上一篇《Spring4新特性——泛型限定式依赖注入》,接下来我们看看Spring4的其他改进。

 

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;难道忘了吗?

 

 

9
1
分享到:
评论
4 楼 acheng3926 2018-01-18  

    [*]
3 楼 aaa110 2014-06-13  
不得不说你是牛人
2 楼 jinnianshilongnian 2014-03-15  
userapplewings 写道
在您这里学到不少东西,非常感谢,不知道有没有关于spring4 websocket的内容呢?

没有
1 楼 userapplewings 2014-03-14  
在您这里学到不少东西,非常感谢,不知道有没有关于spring4 websocket的内容呢?

相关推荐

    Spring4.X最新帮助文档带视图结构树的

    - **核心容器改进(Core Container Improvements):** 在核心容器方面进行了一系列改进,提升了性能和易用性。 - **通用Web改进(General Web Improvements):** 对Web模块进行了增强,提高了处理Web请求的能力。 -...

    spring源码阅读——1.spring-core-3.2.9

    通过分析`readme.txt`,我们可以获得关于这个版本的更多细节,例如新特性、已知问题和改进之处。同时,了解XML配置文件的结构和作用,也能使我们在实际项目中更有效地配置和使用Spring。 总之,Spring Core 3.2.9...

    北京动力节点-reyco-郭-spring4讲义

    【压缩包子文件的文件名称列表】仅有一个文件"spring.pdf",可以推测这份PDF文档包含了整个Spring 4课程的讲义内容,可能涵盖了Spring 4的基本概念、核心组件、配置方式、IoC容器、AOP原理、MVC框架、数据访问(如...

    Spring Framework 6 中文文档

    核心技术章节深入探讨了Spring的核心组件——IoC(Inversion of Control)容器。IoC容器是Spring的核心,负责管理对象的生命周期和依赖关系。Bean是容器中的基本单元,它们被容器初始化、装配和管理。Spring提供了...

    Spring3.1.3 Ioc在Web容器中的建立

    标题 "Spring3.1.3 Ioc在Web容器中的建立" 涉及的是Spring框架的一个关键特性——依赖注入(Dependency Injection,简称DI),以及如何在Web应用环境中配置和使用它。Spring是Java开发中最流行的轻量级框架之一,...

    JDK8 + Tomcat8.0 + SpringMVC4 + Spring4 + Hibernate4 + MySQL5.6

    这个组合——"JDK8 + Tomcat8.0 + SpringMVC4 + Spring4 + Hibernate4 + MySQL5.6"——代表了一种常见的Web应用架构,每个组件都有其独特的功能和价值。接下来,我们将深入探讨这些技术的核心知识点。 首先,JDK8...

    spring核心包

    这个版本的Spring框架在2007年发布,引入了许多重要的改进和新特性。其中,IoC容器是Spring的核心,它负责管理对象的生命周期和装配。通过配置文件或注解,开发者可以声明对象及其依赖关系,容器会自动创建并管理...

    spring3.0_doc_api

    1. **依赖注入(Dependency Injection, DI)**:Spring的核心特性之一,允许对象之间的依赖关系在运行时被外部容器管理,而不是由代码硬编码。这提高了代码的可测试性和可维护性。 2. **IoC容器(Inversion of ...

    spring4X企业应用实战随书guangpan

    Spring4X标签明确指出了本书关注的核心——Spring 4.x版本,这个版本包含了众多改进和新特性,使得Spring更加适应现代Java开发的需求。 Spring框架是Java企业级应用开发的重要工具,它以其模块化、依赖注入...

    spring-framework-5.3.23 源码

    首先,让我们深入了解一下Spring的核心概念——依赖注入(Dependency Injection,简称DI)。在Spring框架中,DI是通过容器来管理对象的生命周期和相互依赖关系。这使得开发者可以避免硬编码依赖,提高代码的可测试性...

    spring框架简单教程

    本教程将向您介绍Spring的基本概念、发展历程以及如何利用其核心特性——控制反转(IoC)和依赖注入(DI)来简化软件设计。 ### Spring框架概述 Spring是一个开源的Java平台,它主要为开发企业级应用提供了丰富的...

    Spring完整Jar包

    核心容器包括了Spring的核心模块——Bean工厂(BeanFactory)和应用上下文(ApplicationContext)。BeanFactory是Spring的基本容器,用于管理对象的生命周期和依赖关系;ApplicationContext则扩展了BeanFactory,...

    spring 4.3.2 开发全 jar 包

    在这个版本中,Spring团队继续优化了核心容器、数据访问、Web应用以及与其他框架的集成。 首先,让我们深入了解一下Spring的核心组件——Spring Core Container。它是整个Spring框架的基础,主要包括Bean Factory和...

    spring4.2的lib包

    例如,核心容器的相关类、AOP代理的实现、Web MVC的控制器和视图解析逻辑,以及对其他数据访问技术的抽象和适配器等。这个单一的JAR文件使开发者能够在项目中快速引入Spring框架,而无需手动管理大量的依赖库。 ...

    模拟spring和工具jar包

    1. **容器**:在Spring中,ApplicationContext是核心容器,负责管理Bean的生命周期和装配。在模拟中,可能会有一个类似的类或接口,用于创建和管理对象。 2. **Bean**:在Spring中,Bean是被容器管理的对象,它们的...

    spring-framework 中文文档.pdf

    Spring Framework 提供了一种灵活的方式来构建应用程序,通过其核心特性——依赖注入(Dependency Injection, DI)和面向切面编程(Aspect Oriented Programming, AOP),使得开发者能够更加关注业务逻辑而不是复杂...

    Pro Spring 5 英文原版

    1. **模块化结构**:Spring框架由多个模块组成,如Core Container(核心容器)、Data Access/Integration(数据访问/集成)、Web、AOP(面向切面编程)和Test等。每个模块都有特定的功能,例如,Core Container包含...

Global site tag (gtag.js) - Google Analytics