Spring - lookup-method方式实现依赖注入
引言
假设一个单例模式的bean A需要引用另外一个非单例模式的bean B,为了在我们每次引用的时候都能拿到最新的bean B,我们可以让bean A通过实现ApplicationContextWare来感知applicationContext(即可以获得容器上下文),从而能在运行时通过ApplicationContext.getBean(String beanName)的方法来获取最新的bean B。但是如果用ApplicationContextAware接口,就让我们与Spring代码耦合了,违背了反转控制原则(IoC,即bean完全由Spring容器管理,我们自己的代码只需要用bean就可以了)。
所以Spring为我们提供了方法注入的方式来实现以上的场景。方法注入方式主要是通过<lookup-method/>标签。
实例
下面我们用一个例子来说明lookup-method的用法。
假设有一个果盘,果盘里放了一些水果,比如苹果,香蕉等,我们希望我们每次在果盘里拿到的都是最新鲜的水果。
java代码:
// 定义一个水果类
public class Fruit {
public Fruit() {
System.out.println("I got Fruit");
}
} // 苹果
public class Apple extends Fruit {
public Apple() {
System.out.println("I got a fresh apple");
}
} // 香蕉
public class Bananer extends Fruit {
public Bananer () {
System.out.println("I got a fresh bananer");
}
} // 水果盘,可以拿到水果
public abstract class FruitPlate{
// 抽象方法获取新鲜水果
protected abstract Fruit getFruit();
}
spring配置:
<!-- 这是2个非单例模式的bean -->
<bean id="apple" class="cn.com.willchen.test.di.Apple" scope="prototype"/>
<bean id="bananer" class="cn.com.willchen.test.di.Bananer " scope="prototype"/> <bean id="fruitPlate1" class="cn.com.willchen.test.di.FruitPlate">
<lookup-method name="getFruit" bean="apple"/>
</bean>
<bean id="fruitPlate2" class="cn.com.willchen.test.di.FruitPlate">
<lookup-method name="getFruit" bean="bananer"/>
</bean>
测试代码:
public static void main(String[] args) {
ApplicationContext app = new ClassPathXmlApplicationContext("classpath:resource/applicationContext.xml");
FruitPlate fp1= (FruitPlate)app.getBean("fruitPlate1");
FruitPlate fp2 = (FruitPlate)app.getBean("fruitPlate2");
fp1.getFruit();
fp2.getFruit();
}
测试结果:
I got Fruit
I got a fresh apple
I got Fruit
I got a fresh bananer
示例说明:
从上面例子我们可以看到,在代码中,我们没有用到Spring的任何类和接口,实现了与Spring代码的耦合。
其中,最为核心的部分就是lookup-method的配置和FruitPlate.getFruit()方法。上面代码中,我们可以看到getFruit()方法是个抽象方法,我们并没有实现它啊,那它是怎么拿到水果的呢。这里的奥妙就是Srping应用了CGLIB(动态代理)类库。Spring在初始化容器的时候对配置<lookup-method/>的bean做了特殊处理,Spring会对bean指定的class做动态代理,代理<lookup-method/>标签中name属性所指定的方法,返回bean属性指定的bean实例对象。每次我们调用fruitPlate1或者fruitPlate2这2个bean的getFruit()方法时,其实是调用了CGLIB生成的动态代理类的方法。关于CGLIB大家可自行在网上查阅。
lookup-method实现方式说明:
<bean class="beanClass">
<lookup-method name="method" bean="non-singleton-bean"/>
</bean>
method是beanClass中的一个方法,beanClass和method是不是抽象都无所谓,不会影响CGLIB的动态代理,根据项目实际需求去定义。non-singleton-bean指的是lookup-method中bean属性指向的必须是一个非单例模式的bean,当然如果不是也不会报错,只是每次得到的都是相同引用的bean(同一个实例),这样用lookup-method就没有意义了。
另外对于method在代码中的签名有下面的标准:
<public|protected> [abstract] <return-type> theMethodName(no-arguments);
public|protected要求方法必须是可以被子类重写和调用的;
abstract可选,如果是抽象方法,CGLIB的动态代理类就会实现这个方法,如果不是抽象方法,就会覆盖这个方法,所以没什么影响;
return-type就是non-singleton-bean的类型咯,当然可以是它的父类或者接口。
no-arguments不允许有参数。
Spring - lookup-method方式实现依赖注入的更多相关文章
- Java Spring学习笔记----Bean的依赖注入(设值注入方式)1
Spring常用的两种依赖注入方式:一种是设值注入方式,利用Bean的setter方法设置Bean的属性值:另一种是构造注入,通过给Bean的构造方法传递参数来实现Bean的属性赋值: 1.设值注入方 ...
- 深入浅出spring IOC中三种依赖注入方式
深入浅出spring IOC中三种依赖注入方式 spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则来消减计算机程序的耦合问题,控制反转一般分为两种类型,依赖注入和 ...
- 转:深入浅出spring IOC中四种依赖注入方式
转:https://blog.csdn.net/u010800201/article/details/72674420 深入浅出spring IOC中四种依赖注入方式 PS:前三种是我转载的,第四种是 ...
- Spring理论基础-控制反转和依赖注入
第一次了解到控制反转(Inversion of Control)这个概念,是在学习Spring框架的时候.IOC和AOP作为Spring的两大特征,自然是要去好好学学的.而依赖注入(Dependenc ...
- Spring IOC(三)依赖注入
本系列目录: Spring IOC(一)概览 Spring IOC(二)容器初始化 Spring IOC(三)依赖注入 Spring IOC(四)总结 目录 1.AbstractBeanFactory ...
- spring学习(二)---依赖注入
spring第二个特性是依赖注入. 学习依赖注入,首先应该明白两个问题:1,谁依赖谁:2,谁注入,注入什么? 首先还是看代码: 还是这个bean: package testSpring.busines ...
- 7 -- Spring的基本用法 -- 3... Spring 的核心机制 : 依赖注入
7.3 Spring 的核心机制 : 依赖注入 Spring 框架的核心功能有两个. Spring容器作为超级大工厂,负责创建.管理所有的Java对象,这些Java对象被称为Bean. Spring容 ...
- Spring的自动装配与依赖注入
Spring的自动装配与依赖注入 装配 = 创建Bean + 注入Bean 创建Bean 自动发现 显式注册Bean 注入Bean 基于配置的注入 自动注入 Spring的装配分为显式装配和隐式装配, ...
- IOC和AOP使用扩展 多种方式实现依赖注入
多种方式实现依赖注入 1.Spring 使用setter访问器实现对属性的赋值, 2.Spring 构造constructor方法赋值, 3.接口注入 4.Spring P命名空间注入直接量 sett ...
- Spring IOC(五)依赖注入
Spring IOC(五)依赖注入 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 一.autowire 五种注入方式测试 ...
随机推荐
- react+flux编程实践(一) 基础篇
1. React概览 最初听到React而还未深入了解它时,大多数人可能和我的想法一样:难道又是一个新的MVC/MVVM前端framework?深入了解后发现不是这么一回事,React关注的东西很单纯 ...
- Android开发 去掉标题栏方法 摘记
1.用代码里实现 提示:这句代码要写在Activity中的setContentView()方法前面. 2.在清单文件(Androidmanifest.xml)里面实现 android:theme= ...
- 【Ubuntu16】apt-get安装MariaDB
一.Mysql背景信息 Mysql在互联网早期就流行了,追求速度.简单.坚持开源.几乎支持所有操作系统.完全支持多用户.多线程,支持海量数据存储,采用MyISAM.InnoDB两大存储引擎优势互补.但 ...
- BotVS开发基础—2.2 下限价单 交易
代码 import json def main(): Log("ORDER_STATE_PENDING:", ORDER_STATE_PENDING, ", ORDER_ ...
- 《Java从入门到放弃》JavaSE入门篇:面向对象概念(入门版)
要知道什么是面向对象,你首先要有个对象吧,所以······没有对象的可以回家洗洗睡了· 好吧,前面是开玩笑,要说明什么是面向对象,我们还是先 例子: 小呆:"小傻,你今天早餐吃的什么?&qu ...
- LaTeX的表格插入与排版
关于LaTex中的图表问题的几篇有用的文章 Graphics and Colour with LaTeX 有关在LaTex中插图和使用颜色的在线指导. Figure'ing and Picture' ...
- Electron 实战桌面计算器应用
前言 Electron 是一个搭建跨平台桌面应用的框架,仅仅使用 JavaScript.HTML 以及 CSS,即可快速而容易地搭建一个原生应用.这对于想要涉及其他领域的开发者来说是一个非常大的福利. ...
- Java集合框架学习(一)List
先附一张Java集合框架图. 从上面的集合框架图可以看到,Java集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射.Coll ...
- Linux上Oracle自动启停方案
环境 CentOS 6 x86_64, Oracle 11g R2 方案 Oracle在$ORACLE_HOME/bin目录下提供了dbstart和dbshut两个脚本来启动和停止Oracle.d ...
- Microsoft .Net Remoting系列专题之二
Microsoft .Net Remoting系列专题之二 一.远程对象的激活 在Remoting中有三种激活方式,一般的实现是通过RemotingServices类的静态方法来完成.工作过程事实上是 ...