zoukankan      html  css  js  c++  java
  • Spring总结 1.装配bean

    本随笔内容要点如下:

    • 依赖注入
    • Spring装配bean的方式
    • 条件化装配

    一、依赖注入

      我理解的依赖注入是这样的:所谓的依赖,就是对象所依赖的其他对象。Spring提供了一个bean容器,它负责创建应用程序中的bean并通过依赖注入来协调这些对象之间的关系,实现自动创建与管理所创建的对象。我们只需要通过配置来命令Spring提供的容器来完成bean的装配。

    二、Spring装配bean的方式

      在Spring中,装配bean有三种方式:

    1. 通过xml进行配置
    2. 通过Java进行配置
    3. 通过注解来自动扫描并配置

      先使用xml进行举例:

     1 package cn.powerfully.domain;
     2 
     3 public class ABean {
     4     private String str;
     5     private double num;
     6 
     7     public ABean() {
     8     }
     9 
    10     public ABean(String str, double num) {
    11         this.str = str;
    12         this.num = num;
    13     }
    14 
    15     public String getStr() {
    16         return str;
    17     }
    18 
    19     public void setStr(String str) {
    20         this.str = str;
    21     }
    22 
    23     public double getNum() {
    24         return num;
    25     }
    26 
    27     public void setNum(double num) {
    28         this.num = num;
    29     }
    30 }

      在xml中配置如下

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="http://www.springframework.org/schema/beans
     5                         http://www.springframework.org/schema/beans/spring-beans.xsd">
     6 
     7 
     8     <bean id="aBean" class="cn.powerfully.domain.ABean">
     9         <constructor-arg name="str" value="bean"/>
    10         <constructor-arg name="num" value="3.1415926"/>
    11     </bean>
    12 
    13 </beans>

       使用bean标签来表示装载一个bean到Spring容器,默认该bean为单例,即容器中只有一个该类对象。对于字段的注入,上面使用了构造器注入,Spring还支持setter注入,通过<property>标签进行注入,具体的可以参考帮助文档。为了简化,spring提供了c命名空间和p命名空间,用来简化构造器注入和setter注入,上面的例子可以改编成如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:c="http://www.springframework.org/schema/c"
        xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!-- <bean id="aBean" class="cn.powerfully.domain.ABean" p:str="p namespace" p:num="3.14" /> -->
        <bean id="aBean" class="cn.powerfully.domain.ABean" c:str="c namespace" c:num="3.14" />
    
    </beans>

      其他基本类型和上面的例子一样,直接编写即可。对于注入对象与集合,将有所不同:

     1 package cn.powerfully.domain;
     2 
     3 import java.util.List;
     4 import java.util.Map;
     5 import java.util.Properties;
     6 
     7 public class BBean {
     8 
     9     private ABean aBean;
    10     private List<String> list;
    11     private Map<String, Integer> map;
    12     private Properties props;
    13     
    14     public ABean getaBean() {
    15         return aBean;
    16     }
    17 
    18     public void setaBean(ABean aBean) {
    19         this.aBean = aBean;
    20     }
    21 
    22     public List<String> getList() {
    23         return list;
    24     }
    25 
    26     public void setList(List<String> list) {
    27         this.list = list;
    28     }
    29 
    30     public Map<String, Integer> getMap() {
    31         return map;
    32     }
    33 
    34     public void setMap(Map<String, Integer> map) {
    35         this.map = map;
    36     }
    37 
    38     public Properties getProps() {
    39         return props;
    40     }
    41 
    42     public void setProps(Properties props) {
    43         this.props = props;
    44     }
    45 
    46 }

      实例化该类时,需要注入对象、List、Map、Properties,xml配置如下:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xmlns:c="http://www.springframework.org/schema/c"
     5     xmlns:p="http://www.springframework.org/schema/p"
     6     xsi:schemaLocation="http://www.springframework.org/schema/beans
     7                         http://www.springframework.org/schema/beans/spring-beans.xsd">
     8 
     9     <!-- <bean id="aBean" class="cn.powerfully.domain.ABean" p:str="p namespace" p:num="3.14" /> -->
    10     <bean id="aBean" class="cn.powerfully.domain.ABean" c:str="c namespace" c:num="3.14" />
    11 
    12     <bean id="bBean" class="cn.powerfully.domain.BBean" p:aBean-ref="aBean">
    13         <!-- <property name="aBean" ref="aBean" /> -->
    14         <property name="list">
    15             <list>
    16                 <value>item1</value>
    17                 <value>item2</value>
    18             </list>
    19         </property>
    20         <property name="map">
    21             <map>
    22                 <entry key="key1" value="1" />
    23                 <entry key="key2" value="2" />
    24             </map>
    25         </property>
    26         <property name="props">
    27             <props>
    28                 <prop key="key1">1</prop>
    29                 <prop key="key2">2</prop>
    30             </props>
    31         </property>
    32     </bean>
    33 
    34 </beans>

      如果想注入对象,则需要使用ref属性而不是value属性,ref属性值为bean对象的id。特别注意的是,如果使用p或c命名空间,其格式为c:propertyName-ref。常见的集合注入如上配置。关于具体的配置参见帮助文档,毕竟本随笔只是我的知识点简要回忆。

      接着是Java配置,个人觉得Java配置会比xml配置来得更爽,它具有很强的灵活性。还是使用上面的例子,配置如下:

     1 package cn.powerfully.config;
     2 
     3 import java.util.Arrays;
     4 
     5 import org.springframework.context.annotation.Bean;
     6 import org.springframework.context.annotation.Configuration;
     7 
     8 import cn.powerfully.domain.ABean;
     9 import cn.powerfully.domain.BBean;
    10 
    11 @Configuration
    12 public class BeanConfig {
    13 
    14     @Bean
    15     public ABean aBean() {
    16         return new ABean("java configura", 3.1415);
    17     }
    18 
    19     @Bean
    20     public BBean bBean(ABean aBean) {
    21         BBean bean = new BBean();
    22         bean.setaBean(aBean);
    23         bean.setList(Arrays.asList("item1", "item2"));
    24         return bean;
    25     }
    26 
    27 }

      通过注解@Configuration来表明该类是配置类,通过@Bean来表示该方法返回结果将放入容器,而方法返回结果即实例对象需要自己创建,其中在容器中bean的id为方法名。对于bBean,需要注入aBean对象,只需要在方法中填入参数,接着在代码里面直接引用即可。

       最后,回忆下注解。一般用到的注解为@Component与@Autowired。@Component标记在类上,表示该类需要被实例化并由Spring容器管理。@Autowired表示需要在Spring容器中查找符合的bean来设置到当前属性里,该注解可以用在字段、构造器、setter上。同时,还要开启自动扫描才能实现。

    三、条件化装配

      有时,我们需要动态地来装配bean。当满足一定条件时我们才需要装配这个bean。Spring4之后,注解@Conditional可以实现这个功能。

    1 @Conditional(UserCondition.class)
    2 public class User {}
    3 
    4 public class UserCondition implements Condition {
    5     @Override
    6     public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    7         return false;
    8     }
    9 }

      当UserCondition中matches方法返回真时,才会创建User对象。关于该接口的具体使用请参考另一篇博文(还没写~.~)。

      其中@Profile是其中的一个特例,它也是使用@Conditonal来实现的。配置完该注解后,我们一开始可以通过设置profile类型来管理需要创建哪一系列bean。例如,在Web开发中,我们所选择的数据库可能根据运行时期的不同而不同。例如在开发环境,我们可能使用c3p0、dbcp等作为数据源。而在生产环境中,我们可能使用JNDI数据源。这是我们就可以使用profile了。我们先为不同的配置设置不同的profile,然后再使用时设置profile就行了。具体的还是参考另一篇博文。>_<

      简单例子如下:

      定义交通工具接口

    1 package cn.powerfully.domain;
    2 
    3 public interface Vehicle {}

      定义车与飞机类并实现Vehicle接口:

     1 package cn.powerfully.domain;
     2 
     3 import org.springframework.context.annotation.Profile;
     4 import org.springframework.stereotype.Component;
     5 
     6 @Component
     7 @Profile("car")
     8 public class Car implements Vehicle {
     9     @Override
    10     public String toString() {
    11         return "Car";
    12     }
    13 }
     1 package cn.powerfully.domain;
     2 
     3 import org.springframework.context.annotation.Profile;
     4 import org.springframework.stereotype.Component;
     5 
     6 @Component
     7 @Profile("plane")
     8 public class Plane implements Vehicle {
     9     @Override
    10     public String toString() {
    11         return "Plane";
    12     }
    13 }

      创建配置类

    1 package cn.powerfully.config;
    2 
    3 import org.springframework.context.annotation.ComponentScan;
    4 import org.springframework.context.annotation.Configuration;
    5 
    6 @Configuration
    7 @ComponentScan(basePackages = "cn.powerfully.domain")
    8 public class VehicleConfig {}

      JUnit测试

     1 package cn.powerfully.test;
     2 
     3 import org.junit.Test;
     4 import org.junit.runner.RunWith;
     5 import org.springframework.beans.factory.annotation.Autowired;
     6 import org.springframework.test.context.ActiveProfiles;
     7 import org.springframework.test.context.ContextConfiguration;
     8 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
     9 
    10 import cn.powerfully.config.VehicleConfig;
    11 import cn.powerfully.domain.Vehicle;
    12 
    13 @RunWith(SpringJUnit4ClassRunner.class)
    14 @ContextConfiguration(classes=VehicleConfig.class)
    15 @ActiveProfiles("car")
    16 public class Demo {
    17     @Autowired
    18     private Vehicle vehicle;
    19     
    20     @Test
    21     public void test(){
    22         System.out.println(vehicle);
    23     }
    24 }

      当选用了car时,输出Car,选择plane时,输出了Plane...当然也可以使用xml配置:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="http://www.springframework.org/schema/c"
     4     xmlns:p="http://www.springframework.org/schema/p"
     5     xsi:schemaLocation="http://www.springframework.org/schema/beans
     6                         http://www.springframework.org/schema/beans/spring-beans.xsd">
     7 
     8     <beans profile="car">
     9         <bean id="vehicle" class="cn.powerfully.domain.Car" />
    10     </beans>
    11     
    12     <beans profile="plane">
    13         <bean id="vehicle" class="cn.powerfully.domain.Plane" />
    14     </beans>
    15 
    16 
    17 </beans>

      注意profile属性是位与beans标签上的。

  • 相关阅读:
    Maven下Flex国际化配置
    Adobe AIR and Flex
    jQuery: 刨根问底 attr and prop两个函数的区别
    HTML5[8]: 图文混排,图片与文字居中对齐
    HTML5[7]: 实现网页版的加载更多
    HTML5[6]:多行文本显示省略号
    HTML5[5]:在移动端禁用长按选中文本功能
    HTML5[4]:去除不必要的标签,完全使用css实现样式
    HTML5[3]:中文换行
    HTML5[2]:使用viewport控制手机浏览器布局
  • 原文地址:https://www.cnblogs.com/loading4/p/6291044.html
Copyright © 2011-2022 走看看