Hello,大家好,上两篇博文给大家分享了Spring容器的创建,以及Bean的生命周期,今天这一篇给大家讲解Bean的注入,就是Bean的一些注入方式,配置方式,然后再讲一下作者的一点使用经验,其实这一篇也是比较基础的东西,好了,老套路,文章结构:
单单这一小节,如果往细了说,一篇博文都是不够的,因为知识点比较多,比较杂, 而且,绝大部分都是一辈子用不上的 。所以我想了想,还是直接干脆直接的上重点,很多不用的能提就提一下。
Spring的XML配置文件是DTD格式的,很多人其实对这个XML的开头一些配置都不理,我这里还是提一下:
Beans标签的格式:
<Beans xmlns属性 xmlns属性 ... xsi属性>
xmlns属性定义命名空间,命名空间就是所有文件定义bean时带的前缀,像 aop:config ,这个标签的aop就是aop命名空间 ,没有加命名空间,就是默认的命名空间.
xsi属性是根据全限定名称指定格式文件xsd的.
xmlns属性的格式: xmlns:命名空间="命名空间的全限定名(可以随意命名,命为123都可以)"
xsd 格式: "xmlns定义的命名空间"+"空格"+"xsd文件"
说下指定xsd的作用:当你敲下 的前半段<bea,它个你提示出全部的 。 其实这个就是ide根据xsd文件帮你列出来的。
在xml文件里定义Bean,贼简单的一个:
<bean id="stu" class="com.zdy.Student" > <property name="name"><value>张三</value></property> </bean>
是根据setter方法注入的。大家不要在看什么根据构造函数注入属性了。西坝,博主这么多年都没有过这种操作。都是根据setter注入的。 然后说一下,XML里面有一些特殊字符,要使用转义序列代替,我给个表格:
至于网上说的还有一种:<![CDATA[]]>的搞法,大家忽略掉。一是不方便,二是不支持p命名空间。待会会说到p命名空间.
上面的例子是注入的常量,然后提下bean之间的相互依赖:
<bean id="car" calss="..." /> <bean id="boss" class="..." > <property name="car"> <ref bean="car"></ref> </property> </bean>
其他的一些什么集合注入,级联注入,我就不提了,根本没地用。
上面的配置大家可以看到,贼复杂,而且在配置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="张三" />
然后说下格式:
然后提一下自动注入:大家可以看到如果使用ref标签来注入bean依赖,程序员会死掉的。比如一个Controller层的Bean,依赖的Service层的Bean可能有10几个。一个个的配置了写。肯定是不行的。所以自动注入就出来了。@Autowired注解,后面会讲。这里只是提一下.
然后提一下,标签,用于导入多个xml配置文件到一个xml配置文件中.
上面可以看到,想把Bean注入到Spring容器中,可以使用标签,然后注入一些属性什么的。并且bean之间的引用关系可以使用ref标签。其实工作中这种操作基本没有公司会采纳的。 因为太麻烦了 ,由于是配到ref标签时,真的会死人的。 工作中,对于我们自己创建的bean,肯定是会使用注解的方式来配置的 ,具体使用方法:
<context:component-scan base-package="...">
@Component public class UerDao { ... }
这样,我们的UserDao就注入到了Spring容器中。那么这种配置方式是如何解决相互依赖关系呢?@AutoWired
@Controller public class UserController{ @Autoired private UserService userService; ... }
@Autoired会自动根据类型来把Bean注入进来。这多简单呢?至于一些其他的参数,我就不扩展了。
直接给一个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配置文件,前面的博客讲到过。
好了,其实想把Bean加入到Spring容器中的方法无非是以上三种。而且也都很基础。我说下实际工作当中的一些小经验:
最后给一个比较图,和使用场景图:
最后说一下,作者遇到过的实际的这几种方式的选择: