Spring中的bean装配

装配bean

Spring主要的三种装配机制:

  • 在XML中进行显式配置;
  • 在Java中进行显式配置;
  • 隐式的bean发现机制和自动装配。

 

Spring从两个角度实现自动化装配:

组件扫描:@Component(自定义bean名称)注解  此外,@Named()有类似功能,不建议用

@Configuration

@ComponentScan(指定扫描的基础包)

@ComponentScan(basePackages={“pakage1”,”pakage2”}) 扫描多个基础包

 

自动装配:

 

测试:

@Runwith(SpringJUnit4ClassRunner.Class)在测试开始的时候创建上下文

@ContextConfiguration(classes=XXConfig.class)在那个文件中加载

@Autowired:自动装配不仅能过用在构造器上,而且能够用在属性setter方法上。

此外@Inject也能够代替,它源于Java依赖注入的规范。

@Test

  1. 通过Java装配bean

1 创建配置类 @Configuration

2 生命简单的bean  @Bean

3 借助JavaConfig实现注入

     2.通过XML装配Java

  • 借助于 Spring Tool Suite 创建XML配置文件和管理Spring配置文件
  • 声明一个简单的bean
  • 借助构造器注入初始化bean
  • 构造器注入bean引用 <constructor-arg  ref=”xxxx” />
  • 将字面注入到构造器中 <contructor-arg  value=”xxx” />
  • 使用List装配集合

  <constructor-arg>

                            <list>

                                     <value>xxx</value>

                                     <value>yyy</value>

                            </list>

                     </constructor-arg>

也可以使用Set集合,但不能重复和保证无序。

  • setter属性注入:

强依赖使用构造器注入

<property>元素为属性的Setter方法所提供的功能和<constructor-arg>元素是一样的。前者对应着p-命名空间,后者对应c-命名空间。

  • 将字面注入到属性中

<property name=””, value=”xxxxxx”/>

  < property  name = “abc”>

                            <list>

                                     <value>xxx</value>

                                     <value>yyy</value>

                            </list>

                     </ property >

注意装配引用和装配置字面唯一的区别就是带不带-ref。

如何配置混合装配。

  1. 使用@Import将两个JavaConfig配置类组合在一起

@Configuration

@Import({xxx1Config.class, xxx2Config.class})

     2.在JavaConfig中引用XML配置

@Configuration

@Import(xxx1Config.class )

@ImportResource(“classpath:xxx-config.xml”)

 

        拆分XML配置

同样使用<import resource=”xxx.xml”/>

     在XML配置中引用JavaConfig配置

<bean class=”xxx.Config”/>

<import resource = “xxxx.xml”

高级装配

环境与profile:开发和生产阶段对数据库会有不同的配置。用profile进行bean的激活管理。

在XML中配置profile:可以同时定义三个bean,类型都是javax.sql.DataSource.并且ID都可以相同。那么如何激活某个profile??

使用profile进行测试

Spring提供了@ActiveProfiles注解:

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(classes={xxTestConfig.class})

@ActiveProfiles(“active”)

Public class xxxxxTest{ }

条件化的bean ,Spring4引入了新的@Contional注解

Condition接口matches方法中两个重要的变量:

ConditionContext和AnnotatedTypeMetadata

 

Spring4中的Profile重构,

@Conditional(value={ProfileCondition.class})
@Target(value={METHOD, TYPE})
@Retention(value=RUNTIME)
@Documented

自动装配的歧义性

Spring不能够从多个bean选择并能够自动装配,就会抛出异常。NoUniqueBeanDefinitionException.

解决方案:

  • 标示首选的bean。

@Component

@Primary

Public class IceCream implements Dessert{}

  • 多个首选bean出现歧义的解决方案:限定自动装配的bean

@Qualifier注解是使用限定符的主要方式,与@Autowired和@Inject协同使用。

@Autowired

@Qualifier(“iceCream”) //参数是想要被注入的bean的ID

Public void setDessert(Dessert dessert){

         This.dessert = dessert;

}

  • 解决基于默认的bean ID作为限定符的问题:创建自定义的限定符。

就是在bean声明上添加@Qualifier并且和@Component联用

@Component

@Qualifier(“newname”)//这种情况,newname限定符分配给了IceCream bean。

Public class IceCream implements Dessert {}

能够解决对IceCream类名的任意重构。

  • 使用自定义的限定符注解:解决限定符注解的冲突

通过声明自定义的限定符注解,我们能够同时使用多个限定符,不会再有Java编译器的限制或错误,此外,与原始的@Qualifier并借助于String类型来指定限定符,自定义的限定符更安全。

 

Bean的作用域

Spring定义的作用域:

单例(singleton)

原型(prototype)

会话(session)

请求(request)

使用会话和请求作用域

@Component

@Scope(value=WebApplicationContext.SCOPE_SESSION,

proxyMode=ScopedProxyMode.INTERFACES)

public ShoppingCart cart(){…}

proxyMode=ScopedProxyMode.INTERFACES //代理要实现接口,并调用委托给实现bean。

proxyMode=ScopedProxyMode.TARGET_CLASS//带来要实现具体的类,使用CGLib生成基于类的代理。

在XML中声明作用域代理:

<bean id =”cart”  class=”com.myapp.ShoppingCart” scope=”session”>

         <aop:scoped-proxy  proxy-target-class=”false” />要求基于接口的代理。默认使用CGLib

</bean>

  • 运行时值注入

注入外部的值:

声明属性源并通过spring的Environment来检索属性。

@Configuration

@PropertySource(“xxx/xx/app.properties”)

Public class ExpressiveConfig{

         @Autowired

         Environment env;

         @Bean

         Public BlankDisc disc () {

              Return new BlankDisc(env.getPreoperty(“xxx”), env.getProperty(“xxx”));

}

}

  • 深入学习spring的Environment

String getProperty(String key)

String getProperty(String key, String defaultValue)

T getProperty(String key, Class<T> type)

T getProperty(String key, Class<T> type , T defaultValue)

 

String[] getActiveProfiles():返回激活profile名称的数组。

String[] getdefaultProfiles():返回默认profile名称的数组。

boolean acceptsProfiles(String…profiles):如果environment支持profile的话,就返回true。

  • 使用属性占位符:${xxx}

  1. 使用spring表达式语言进行装配
  • 使用bean的ID来引用bean
  • 调用方法和访问对象的属性
  • 对值进行算术、关系和逻辑运算
  • 集合操作
  1. SpEL样例

#{T(System).currentTimeMillis()}

  • SpEL对bean的装配:

Pubic BlankDisc(@Value(“#{SystemPropreties[‘disc.title’]}”)  String title,

@Value(“#{SystemPropreties[‘disc.artist’]}”)  String artist){

This.title=title;

This.artist=artist;

}//和占位符非常相似

表示字面值:整数、浮点数、String、Boolean值。

引用bean、属性、方法

#{segPeppers}

#{segPeppers.artist}

#{artistSelector.selectArtist()}

#{artistSelector.selectArtist()?.toUpperCase()}//如果方法返回值为null的话,那么SpEL将不会调用toUpperCase()的方法。

在表达式中使用类型以及运算符:

#{2 * T(java.lang.Math).PI * circle.radius}

#{counter.total == 100}

#{counter.total eq 100}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值