spring 动态指定具体实现类

在写接口实现时,有时会有多个实现类。这篇文章介绍在调用时通过传入字符串来指定具体的实现类。

一.接口与实现类:

// 接口
public interface ServiceInterface {
	public void method();
}

// 具体两个实现类
@Service("aService")
public class AServiceImpl implements ServiceInterface {

	@Override
	public void method() {
		System.out.println("the impl is A");
	}

	@Override
	public String toString() {
		return "A";
	}
}

@Service("bService")
public class BServiceImpl implements ServiceInterface {

	@Override
	public void method() {
		System.out.println("the impl is B");
	}

	@Override
	public String toString() {
		return "B";
	}

}

  在实现类中重写了toString() 方法,可以自定义字符串,当调用时传入指定的字符串就能获取到相应的bean。

二.register书写:

@Service("register")
public class Register implements InitializingBean, ApplicationContextAware {
	private Map<String, ServiceInterface> serviceImplMap = new HashMap<>();
	private ApplicationContext applicationContext;

	// 获取spring的上下文
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	// 获取接口实现类的所有bean,并按自己定的规则放入map中
	@Override
	public void afterPropertiesSet() throws Exception {
		Map<String, ServiceInterface> beanMap = applicationContext.getBeansOfType(ServiceInterface.class);
		// 以下代码是将bean按照自己定的规则放入map中,这里我的规则是key:service.toString();value:bean
		// 调用时,参数传入service.toString()的具体字符串就能获取到相应的bean
		// 此处也可以不做以下的操作,直接使用beanMap,在调用时,传入bean的名称
		for (ServiceInterface serviceImpl : beanMap.values()) {
			serviceImplMap.put(serviceImpl.toString(), serviceImpl);
		}
	}

	public ServiceInterface getServiceImpl(String name) {
		return serviceImplMap.get(name);
	}

}

  三.测试类:

     @Resource
	Register register;

	@Test
	public void testService() {
		ServiceInterface service = register.getServiceImpl("A");
		service.method();
		ServiceInterface service2 = register.getServiceImpl("B");
		service2.method();
	}

  运行结果,如图:

------------------------------------------------------------------------------------------

备注:

在spring加载后,获取applicationContext的方法:

实现ApplicationContextAware接口的Bean,在Bean加载的过程中可以获取到Spring的ApplicationContext,这个尤其重要,ApplicationContext是Spring应用上下文,从ApplicationContext中可以获取包括任意的Bean在内的大量Spring容器内容和信息

@Component("informerRegistry")
public final class InformerRegistry implements ApplicationContextAware{

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

  关于spring常用bean扩展接口可参考:http://www.cnblogs.com/xrq730/p/5721366.html

注意:

使用以下方法获取spring上下文时,会启动spring。多次写以下方法,就会启动多个spring容器

ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:META-INF/spring/*.xml");

  

时间: 2024-08-11 07:33:55

spring 动态指定具体实现类的相关文章

Java中的动态代理以及Proxy类的偷瞄

动态代理机制 所谓动态代理,即通过代理类Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. Java动态代理类位于Java.lang.reflect包下,主要涉及到两个类. (1)接口InvocationHandler:该接口中仅定义了一个方法. Object invoke(Object obj, Method method, Object[] args); 在实际使用时,第一个参数obj一般指代理类,method是被代理的方法,args为该方法

Quartz 2.x与Spring 动态整合

一.Quartz简介 Quartz是一个由James House创立的开源项目,是一个功能强大的作业调度工具,可以计划的执行任务,定时.循环或在某一个时间来执行我们需要做的事,这可以给我们工作上带来很大的帮助.例如,你的程序中需要每个月的一号导出报表.定时发送邮件或程序需要每隔一段执行某一任务--等等,都可以用Quartz来解决. Quartz大致可分为三个主要的核心: 1.调度器Scheduler:是一个计划调度器容器,容器里面可以盛放众多的JobDetail和Trigger,当容器启动后,里

Spring 动态代理基础知识

Spring AOP 使用动态代理技术在运行期织入增强的代码,为了揭示 Spring AOP 底层的工作机理,有必要学习涉及的 Java 知识.Spring AOP 使用了两种代理机制:一种是基于 JDK 的动态代理:另一种是基于 CGLib 的动态代理.之所以需要两种代理机制,很大程度上是因为 JDK 本身只提供接口的代理,而不支持类的代理. 1.带有横切逻辑的实例 下面通过具体化代码实现一个性能监视横切逻辑,并通过动态代理技术对此进行改造.在调用每一个目标类方法时启动方法的性能监视,在目标类

spring动态切换数据源(一)

介绍下spring数据源连接的源码类:| 1 spring动态切换连接池需要类AbstractRoutingDataSource的源码 2 /* 3 * Copyright 2002-2017 the original author or authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in comp

Spring2.5学习4.2_Proxy实现动态代理(目标类实现随意接口)

静态代理的缺点是在代理类中绑定了固定的接口,不利于扩展,动态代理则不然,通过动态代理能够对不论什么实现某一接口的类进行功能性增强. 在java中动态代理由InvocationHander来实现. HelloInterface接口 [java] view plaincopy package proxy; public interface HelloInterface { public void sayHello(); } 实现HelloInterface接口的类HelloInterfaceImpl

Spring动态数据源实现读写分离

一.创建基于ThreadLocal的动态数据源容器,保证数据源的线程安全性 package com.bounter.mybatis.extension; /** * 基于ThreadLocal实现的动态数据源容器,保证DynamicDataSource的线程安全性 * @author simon * */ public class DynamicDataSourceHolder { private static final ThreadLocal<String> dataSourceHolde

Spring动态配置多数据源

Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性.而这样的方案就会不同于常见的单一数据实例的方案,这就要程序在运行时根据当时的请求及系统状态来动态的决定将数据存储在哪个数据库实例中,以及从哪个数据库提取数据. 基本信息 1.Spring配置多数据源的方式和具体使用过程. 2.Spring对于多数据源,以数据库表为参照,大体上可以分成两大类情况: 一是,表级上的跨数据库.即,对于不同的数据库却有相同的表(表名和表结构完全相

使用反射和泛型,动态读取XML创建类实例并赋值

[狗刨学习网]unity极致学院,致力于打造业内unity3d培训.学习第一品牌. 前言: 最近小匹夫参与的游戏项目到了需要读取数据的阶段了,那么觉得自己业余时间也该实践下数据相关的内容.那么从哪入手呢?因为用的是Unity3d的游戏引擎,思来想去就选择了C#读取XML文件这个小功能.网上的例子倒也不少,但总是觉得缺点什么.比如读取xml文件之后该如何处理?看到的文章基本上都是手动创建一个目标类的实例,然后手动从读取的XML文件的内容中给刚才创建的目标类实例相关字段赋值.缺点什么呢?对嘞,感觉上

自己动手之使用反射和泛型,动态读取XML创建类实例并赋值

前言: 最近小匹夫参与的游戏项目到了需要读取数据的阶段了,那么觉得自己业余时间也该实践下数据相关的内容.那么从哪入手呢?因为用的是Unity3d的游戏引擎,思来想去就选择了C#读取XML文件这个小功能.网上的例子倒也不少,但总是觉得缺点什么.比如读取xml文件之后该如何处理?看到的文章基本上都是手动创建一个目标类的实例,然后手动从读取的XML文件的内容中给刚才创建的目标类实例相关字段赋值.缺点什么呢?对嘞,感觉上不够简单和智能. 正所谓驱动科技发展的原因就是懒,为了使我们的小工具能够傻瓜到只需要