转载

Spring核心系列之Bean的注入

Hello,大家好,上两篇博文给大家分享了Spring容器的创建,以及Bean的生命周期,今天这一篇给大家讲解Bean的注入,就是Bean的一些注入方式,配置方式,然后再讲一下作者的一点使用经验,其实这一篇也是比较基础的东西,好了,老套路,文章结构:

  1. 基于XML的配置
  2. 基于注解的配置
  3. 基于Spring config 的配置
  4. 几种配置方式的混合使用

1. 基于XML的配置

单单这一小节,如果往细了说,一篇博文都是不够的,因为知识点比较多,比较杂, 而且,绝大部分都是一辈子用不上的 。所以我想了想,还是直接干脆直接的上重点,很多不用的能提就提一下。

1.1 DTD格式

Spring的XML配置文件是DTD格式的,很多人其实对这个XML的开头一些配置都不理,我这里还是提一下:

Spring核心系列之Bean的注入

Beans标签的格式:

<Beans xmlns属性 xmlns属性 ... xsi属性>

  • xmlns属性定义命名空间,命名空间就是所有文件定义bean时带的前缀,像 aop:config ,这个标签的aop就是aop命名空间 ,没有加命名空间,就是默认的命名空间.

  • xsi属性是根据全限定名称指定格式文件xsd的.

  • xmlns属性的格式: xmlns:命名空间="命名空间的全限定名(可以随意命名,命为123都可以)"

  • xsd 格式: "xmlns定义的命名空间"+"空格"+"xsd文件"

说下指定xsd的作用:当你敲下 的前半段<bea,它个你提示出全部的 。 其实这个就是ide根据xsd文件帮你列出来的。

1.2 定义Bean

在xml文件里定义Bean,贼简单的一个:

<bean id="stu" class="com.zdy.Student" >
    <property name="name"><value>张三</value></property>
</bean>

是根据setter方法注入的。大家不要在看什么根据构造函数注入属性了。西坝,博主这么多年都没有过这种操作。都是根据setter注入的。 然后说一下,XML里面有一些特殊字符,要使用转义序列代替,我给个表格:

Spring核心系列之Bean的注入

至于网上说的还有一种:<![CDATA[]]>的搞法,大家忽略掉。一是不方便,二是不支持p命名空间。待会会说到p命名空间.

上面的例子是注入的常量,然后提下bean之间的相互依赖:

<bean id="car" calss="..." />
<bean id="boss" class="..." >
    <property name="car">
        <ref bean="car"></ref>
    </property>
</bean>

其他的一些什么集合注入,级联注入,我就不提了,根本没地用。

1.3 xml简化配置之p命名空间

上面的配置大家可以看到,贼复杂,而且在配置bean之间的相互依赖关系时还要使用ref标签。现在来给大家说下简化配置方式,和自动注入. p命名空间是Spring2.5之后提供的,目的就是为了简化配置,看下效果:

//使用前
<bean id="stu" class="com.zdy.Student" >
    <property name="name"><value>张三</value></property>
</bean>
//使用后
<bran id="stu" class="..." p:name="张三" />

然后说下格式:

  • 对于字面常量: p:属性名=".."
  • 对于引用bean的属性: p:属性名-ref="..."

然后提一下自动注入:大家可以看到如果使用ref标签来注入bean依赖,程序员会死掉的。比如一个Controller层的Bean,依赖的Service层的Bean可能有10几个。一个个的配置了写。肯定是不行的。所以自动注入就出来了。@Autowired注解,后面会讲。这里只是提一下.

然后提一下,标签,用于导入多个xml配置文件到一个xml配置文件中.

2. 基于注解的配置

上面可以看到,想把Bean注入到Spring容器中,可以使用标签,然后注入一些属性什么的。并且bean之间的引用关系可以使用ref标签。其实工作中这种操作基本没有公司会采纳的。 因为太麻烦了 ,由于是配到ref标签时,真的会死人的。 工作中,对于我们自己创建的bean,肯定是会使用注解的方式来配置的 ,具体使用方法:

  1. 在xml文件中或者Java config类中加上扫描路径,这里说下xml的配置:
<context:component-scan base-package="...">
  1. 我们自己写的bean上面加上@Component,@Controller,@Service,@Dao
@Component
public class UerDao {
    ...
}

这样,我们的UserDao就注入到了Spring容器中。那么这种配置方式是如何解决相互依赖关系呢?@AutoWired

@Controller
public class UserController{
    @Autoired
    private UserService userService;
    ...
}

@Autoired会自动根据类型来把Bean注入进来。这多简单呢?至于一些其他的参数,我就不扩展了。

3. 基于Spring config 的配置

直接给一个Config类:

@Configuration
public class UserJedisConfig {

    @Bean
    public CacheManager cacheManager(final RedisTemplate redisTemplate) {
        return new RedisCacheManager(redisTemplate);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate2(final RedisConnectionFactory factory) {
        final RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new RedisObjectSerializer());
        template.afterPropertiesSet();
        return template;
    }
}

@Configuration 内部包含了@Component, 说白了,当这个Bean加入到Spring容器中时,它内部标注了@Bean的方法返回的Bean都会放到Spring容器中。 具体的语法我不多说了。 @Configuration类想加入到Spring容器中有三种方式, 一种是在xml里通过<context:component-scan base-package="...">扫描。一种是通过其他的Config类加上@Componentscan注解,作用是一样的,扫描配置路径下的POJO ,最后一种是在创建容器的时候直接指定这个config类,而不是xml配置文件,前面的博客讲到过。

4. 几种配置方式的混合使用

好了,其实想把Bean加入到Spring容器中的方法无非是以上三种。而且也都很基础。我说下实际工作当中的一些小经验:

  1. 注解大于xml配置。大家自己也可以感觉到注解的方便。
  2. 自己写的bean全部使用注解来注入到容器中。至于容器启动的时候是使用xml文件还是Config类,这都无所谓。只要加了自动扫描即可。
  3. 集成一些三方的框架(如Jedis),需要放入三方的bean到Spring容器中时,这时候没办法使用注解,可以使用xml文件配置或者config类配置。

最后给一个比较图,和使用场景图:

Spring核心系列之Bean的注入
Spring核心系列之Bean的注入

最后说一下,作者遇到过的实际的这几种方式的选择:

  1. 之前在某家房地产公司用到的是"XML+注解",这种方式还是比较多见,比较传统的。Web项目,容器启动以来一个xml文件,然后xml文件中配置扫描的跟路径,自己写的Bean放在路径下面并加上类似于@Componenet的注解,依赖关系依赖于@Autowired注解。如果引用了一些三方的框架,想使用一些框架自带的Bean,就在xml中配置标签加到容器里面去。这是比较传统的Spring容器使用方式。
  2. Spring boot,用过或者了解过Spring boot的小伙伴应该知道,Spring boot中是没有xml文件的,容器启用依赖一个自带的config类,这个config类会自动扫描跟路径之下的,所以我们开发的类只要加上了@Component类似的注解都会被加入到容器当中。 依赖一些三方的框架的Bean,一般情况下,Spring boot会有一些auto注入机制,自动根据配置的参数创建Bean并自动注入bean到容器中 。开发者直接@Autowired就可以使用。特殊情况下才会自己写一个config类来注入一下Spring boot没有自带的三方bean。为什么用过Spring boot的小伙伴都觉得Spring boot比较简洁呢?你想一想,如果你要使用Jedis,只需要pom引入即可。然后就直接@Autowired注入相应的bean,根本不需要配置。这也是Spring boot最最核心的一个特色。后期有机会讲Spring boot时给大家分享这种自动注入是如何实现的。
原文  https://juejin.im/post/5a530b4bf265da3e2f00cad3
正文到此结束
Loading...