这个是接着上一篇写的,这章内容较多,分开来记录一下。。。

三、处理自动装配的歧义性

自动装配让spring完全负责bean引用注入到构造参数和属性中,不过,仅有一个bean匹配所需的结果时,自动装配才是有效的。如果不仅有一个bean能够匹配的话,这种歧义性会阻碍spring自动装配属性、构造参数或方法参数。虽然这种歧义性十分罕见,但是我看了spring解决方法后,感觉spring提供的是一种这类问题的解决办法,显然在这里主要学习的是这种解决此类问题的思想。

//这里是提供了这种特殊情况的demo,有一个方法,需要自动装配Dessert接口
@Autowired
public void setDessert(Dessert dessert){
this.dessert = dessert;
} //但是这个Dessert接口却有三个实现类,这就有点尴尬了,spring自动装配的时候到底要装配哪个实现类呢..... spring会报NoUniqueBeanDefinitionException错误的 @Component
public class Cake implements Dessert{......} @Component
public class Cookies implements Dessert{......} @Component
public class IceCream implements Dessert{......} //使用@Primary 注解标注首选bean
@Primary
@Component
public class IceCream implements Dessert{......} <bean id="iceCream" class="com.desserteater.IceCream" primary="true" /> //但是两个同时加上@Primary注解呢!!!spring中会有@Qualifier注解
@Autowired
@Qualifier("iceCream")
public void setDessert(Dessert dessert){
this.dessert = dessert;
} //但是这种方式使用的是bean ID,限制符与要注入的bean是紧耦合的,对类名称的改动都会导致限定符失效,但是spring中允许为bean设置自己的限定符
@Component
@Qualifier("cold")
public class IceCream implements Dessert{......} @Autowired
@Qualifier("cold")
public void setDessert(Dessert dessert){
this.dessert = dessert;
} //但是如果是两个实现类具有相同特点的限制符呢!!!这个考虑的也太全面了吧,程序员就是要有这种精神的,哈哈哈,就是下面这种情况呢..... @Component
@Qualifier("cold")
@Qualifier("creamy")
public class IceCream implements Dessert{......} @Component
@Qualifier("cold")
@Qualifier("fruity")
public class Popsicle implements Dessert{......} //Java 中不允许出现在同一个条目上出现相同类型的多个注解的,唉,终极办法:自定义限制符注解,这个好牛叉牛叉...
//这个对应着就是@Qualifier("cold")
@Target({ElementType.CONSTRUCAOR, ElementType.FILELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
Public @interface Cold{} //这个对应着就是@Qualifier("creamy")
@Target({ElementType.CONSTRUCAOR, ElementType.FILELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
Public @interface Creamy{} //这个对应着就是@Qualifier("fruity")
@Target({ElementType.CONSTRUCAOR, ElementType.FILELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
Public @interface Fruity{} //大功告成,这就彻底解决那个问题了,你在有多少的我也不怕了,嘿嘿嘿,完美的解决这个问题了,spring中太美妙了,这种思想真的让人受益匪浅
@Component
@Cold
@Creamy
public class IceCream implements Dessert{......} @Component
@Cold
@Fruity
public class Popsicle implements Dessert{......} @Autowired
@Cold
@Creamy
public void setDessert(Dessert dessert){
this.dessert = dessert;
}

四、bean的作用域

在默认情况下,spring应用上下文中所有的bean都是以单例的形式创建的,也就是说,不管给定的一个bean被注入到其他bean多少次,每次所注入的都是同一个实例。大多数情况下,单例bean是很理想的方案。初始化和垃圾回收对线实例所带来的成本只留给一些小规模的任务,在这些任务中,让对象保持无状态并且在应用中反复用这些对象可能并不合理。

spring中为解决这个问题,定义了多种作用域,可以基于这些作用域创建bean:

1)单例(Singleton):在整个应用中,只创建bean的一个实例

2)原型(Prototype):每次注入或者通过spring应用上下文获取的时候,都会创建一个新的bean的实例

3)会话(Session):在web应用中,为每个会话创建一个bean实例

4)请求(Request):在web应用中,为每个请求创建一个bean实例

//Prototype 原型作用域的配置方式
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Notepad{......} <bean id="notepad" class="com.myapp.Notepad" scope="prototype" /> //Session 会话和 Request 请求作用域
//在电商领域的 处理购物车bean 会话作用域是最合适的
@Component
@Scope(
value=WebApplicationContext.Scope.SESSION,
ProxyMode=ScopedProxyMode.INTERFACES)
Public ShoppingCart cart(){......} @Component
Public class StoreService(){ //StoreService是一个单例bean,会在spring应用上下文加载的时候创建,当它创建的时候,会试图将ShoppingCart bean注入到set方法中,但是ShoppingCart bean是会话作用域,此时并不存在,直到某个用户进入系统,创建会话之后才会出现ShoppingCart 的实例
@Autowired
public void setShoppingCart(ShoppingCart shoppingCart){
this.shoppingCart = shoppingCart;
}
} /*
这里需要详细讲解一下ProxyMode
系统中,会有多个ShoppingCart 的实例,每个用户一个,我们希望当StoreService处理购物车的时候,它所使用的ShoppingCart 实例恰好是当前会话所对应的那一个 spring并不会将实际的ShoppingCart bean注入到StoreService中,spring会注入一个到ShoppingCart bean的代理,这个代理会暴露于ShoppingCart 相同的方法,StoreService会认为它就是一个购物车 当StoreService 调用 ShoppingCart 的方法时,代理会对其进行懒解析并调用委托给会话作用域内真正的ShoppingCart bean 这个东西好牛气的样子,这里涉及到了代理模式
*/ //注意:ScopedProxyMode.INTERFACES 表明这个代理要实现ShoppingCart接口,并将调用委托给实现bean
//注意:ScopedProxyMode.TARGET_CLASS 实现的是一个具体的类的话,spring必须使用CGLib 来生成基于类的代理 //XML中实现作用域的配置 这里用到了AOP Spring中面向切面
<bean id="cart" class="com.myapp.ShoppingCart">
<aop:scoped=proxy /> //spring会默认CGLib创建目标类的代理
</bean> //这种 proxy-target-class="false" spring会创建基于接口的代理
<bean id="cart" class="com.myapp.ShoppingCart">
<aop:scoped=proxy proxy-target-class="false" />
</bean>

 五、运行时值注入

这节主要讲的就是spring中的表达式语言SpEL,其他的基本上没有特别重要的,值得思考的知识点。

spring提供了两种在运行时求值的方式:

(1)属性占位符(Property placeholder)

(2)Spring 表达式语言(SpEL)

属性占位符的语法是:${.....}

主要来说一下Spring 表达式语言(SpEL)

1、SpEL拥有很多特性,主要包括:

1)使用bean的ID来应用bean

2)调用方法和访问对象的属性

3)对值进行算术、关系和逻辑运算

4)正则表达式匹配

5)集合操作

2、SpEL样例

1)表示String值、浮点数、Boolean值

#{3.14159}

#{9.87E4}  对应着 98700

#{“hello”}

#{true}

2)引用bean、属性和方法

#{sgtPeppers}

#{sgtPeppers.artist}

#{sgtPeppers.selectArtist()}

#{sgtPeppers.selectArtist().toUpperCase()}

#{sgtPeppers.selectArtist()?.toUpperCase()}  避免出现空值,出现?避免出现空值

3)在表达式中使用类型

T{java.lang.Math}

T{java.lang.Math}.PI

T{java.lang.Math}.random()

4)SpEL运算符

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

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

#{disc.title + 'by' + disc.artist}

#{counter.total == 100}

#{counter.total eq 100}

#{score > 100 ? "winner" : "loser"}

5)计算正则表达式

#{admin.email matches '[a-zA-Z0-9._%+-]+@[a-zA-Z0-9._]+\\.com'}

6)计算集合

#{jukebox.songs[4].title}

#{jukebox.songs[T(java.lang.Math).random * jukebox.songs.size()].title}

#{jukebox.songs.?[artist eq 'Aerosmith']} 过滤歌曲,得到所有属性为Aerosmith的歌曲的小的集合

#{jukebox.songs.^[artist eq 'Aerosmith']}  查询集合中第一个属性为Aerosmith的歌曲

#{jukebox.songs.![title]} 投影运算符,将集合中的特定的属性放到一个新集合中去

#{jukebox.songs.?[artist eq 'Aerosmith']}.![title] 混合使用,把作者是Aerosmith的title属性放到一个集合中去

四、spring中高级装配(2)的更多相关文章

  1. 三、spring中高级装配(1)

    大概看了一下第三章的内容,我从项目中仔细寻找,始终没有发现哪里有这种配置,但是看完觉得spring还有这么牛B的功能啊,spring的厉害之处,这种设计程序的思想,很让我感慨... 一.环境与prof ...

  2. Spring高级装配

    Spring高级装配 目录 一.Profile(根据开发环境创建对应的bean) 二.条件化的创建bean(根据条件创建bean) 三.处理自动装配歧义性(指定首选bean.限定符限制bean) 四. ...

  3. Spring(3)——装配 Spring Bean 详解

    装配 Bean 的概述 前面已经介绍了 Spring IoC 的理念和设计,这一篇文章将介绍的是如何将自己开发的 Bean 装配到 Spring IoC 容器中. 大部分场景下,我们都会使用 Appl ...

  4. J2EE进阶(四)Spring配置文件详解

    J2EE进阶(四)Spring配置文件详解 前言 Spring配置文件是用于指导Spring工厂进行Bean生产.依赖关系注入(装配)及Bean实例分发的"图纸".Java EE程 ...

  5. Spring系列七:Spring 自动装配

    相思相见知何日?此时此夜难为情. 概述 在Spring框架中,在配置文件中声明bean的依赖关系是一个很好的做法,因为Spring容器能够自动装配协作bean之间的关系.这称为spring自动装配. ...

  6. Spring自动装配(二)

    为什么Spring要支持Autowire(自动装配) 先写几个类,首先定义一个Animal接口表示动物: 1 public interface Animal { 2 3 public void eat ...

  7. Spring 自动装配 Bean

    Spring3系列8- Spring 自动装配 Bean 1.      Auto-Wiring ‘no’ 2.      Auto-Wiring ‘byName’ 3.      Auto-Wiri ...

  8. Axis2(7):将Spring的装配JavaBean发布成WebService

    在现今的Web应用中经常使用Spring框架来装载JavaBean.如果要想将某些在Spring中装配的JavaBean发布成WebService,使用Axis2的Spring感知功能是非常容易做到的 ...

  9. Spring注解装配

    Spring 自动装配的主机有 @Autowired.@Intect.@Resource @Autowired是byType的, @Resource是byName的.我们一般用@Atutowired. ...

随机推荐

  1. CentOS6.0忘记root密码解决办法

    说明操作系统:CentOS 6.0遇到问题:忘记管理员账号root的密码,进不了系统解决办法:重置root密码为123456操作: 开机启动系统,在进入系统之前按键盘上面的Esc键,会进入下面的界面 ...

  2. 《StackGAN: Text to Photo-realistic Image Synthesis with Stacked GAN》论文笔记

    出处:arxiv 2016 尚未出版 Motivation 根据文字描述来合成相片级真实感的图片是一项极具挑战性的任务.现有的生成手段,往往只能合成大体的目标,而丢失了生动的细节信息.StackGAN ...

  3. 关于ArcGis for javascrept查询ArcGis server图层信息的方式

    方式一: queryTask方式: 该方式用于单个图层的条件查询(不能跨图层查询) 1. 创建query对象 query = new esri.tasks.Query(); 2. 给query对象设置 ...

  4. jetbrains软件使用

    1.注册(有条件的话建议使用官方渠道注册https://www.jetbrains.com/store) 2018 license server http://idea.congm.in 2.禁用双击 ...

  5. 切换或者用户登录时 出现 显示 -bash-4.2$ 问题 的解决

    集群的普通用户在登录用户或者切换用户时,出现 -bash-4.2$ 的状态: [goldwind@TR-OS-DB 9.4]#su postgres bash-4.2$ 原因:在linux下通过use ...

  6. python 高阶函数三 filter()和sorted()

    一.filter()函数 filter()接收一个函数和一个序列.filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素. >>> ...

  7. bzoj 1103: [POI2007]大都市meg【dfs序+树状数组】

    很明显的暗示,就是在树的dfs序上维护树状数组,加减的时候差分即可 #include<iostream> #include<cstdio> #include<cstrin ...

  8. 【NOIP2006】作业调度方案 {语文难题}

    Description: 我们现在要利用 m 台机器加工 n 个工件,每个工件都有 m 道工序,每道工序都在不同的指定的机器上完成.每个工件的每道工序都有指定的加工时间.  每个工件的每个工序称为一个 ...

  9. 【Android跨进程】IPC总结

    前言 IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程.两个进程可以是两个独立的app也可以是一个app的两个 ...

  10. JavaScript 入门案例

    四.  JavaScript 入门案例 在看本节之前,笔者建议您先看 JavaScript 基础篇  https://www.cnblogs.com/IT-LFP/p/10945884.html 1. ...