springboot的服务定位模式

一、文件解析器的例子

在开发中我们可能会解析CSV,JSON等文件类型,显然要用策略模式

 我们先定义一个Parser接口

public interface Parser {
  
  void parse(String input);
}

Parser接口的实现类有JSONParser,CSVParser

@Component("CSV")
public class CSVParser implements Parser{

  @Override
  public void parse(String input) {
    System.out.println("csv");
  }
}
@Component("JSON")
public class JSONParser implements Parser{

  @Override
  public void parse(String input) {
    System.out.println("json");
  }
}

然后我们定义一个工厂来获取Parser对象

public interface ParserFactory {
  
  Parser getParser(ContentType type);

}

在该工厂方法的参数是一个枚举

public enum ContentType {
  JSON,
  XML,
  TEXT,
  HTML,
  IMAGE,
  OTHER;
}

 写一个配置类

@Configuration
public class ParserConfig {
  
  @Bean
  public FactoryBean serviceLocatorFactoryBean(){
    ServiceLocatorFactoryBean factoryBean = new ServiceLocatorFactoryBean();
    factoryBean.setServiceLocatorInterface(ParserFactory.class);
    return factoryBean;
  }

}

测试

 @Autowired
  private ParserFactory parserFactory;

  @Test
  void contextLoads() {
    Parser parser = parserFactory.getParser(ContentType.JSON);
    parser.parse("{'name':'John'}");
  }

 二、原理

        ServiceLocatorFactoryBean实现了接口FactoryBean和InitializingBean,实现InitializingBean会在初始化ServiceLocatorFactoryBean调用afterPropertiesSet方法,具体实现如下代码

	@Override
	public void afterPropertiesSet() {
		if (this.serviceLocatorInterface == null) {
			throw new IllegalArgumentException("Property 'serviceLocatorInterface' is required");
		}

		// Create service locator proxy.
		this.proxy = Proxy.newProxyInstance(
				this.serviceLocatorInterface.getClassLoader(),
				new Class<?>[] {this.serviceLocatorInterface},
				new ServiceLocatorInvocationHandler());
	}

        在afterPropertiesSet主要给ServiceLocatorFactoryBean的成员变量proxy赋值,生成代理对象,其中接口就是我们前面的ParserFactory。

        我们知道实现FactoryBean可以帮助我们创建bean,其中getObject可以获得bean,实现内容如下 

@Override
	@Nullable
	public Object getObject() {
		return this.proxy;
	}

 getObject返回的ParserFactory的代理对象,生成动态代理方式是采用JDK代理,主要关注invoke方法,ServiceLocatorFactoryBean的内部类,实现类接口InvocationHandler

	@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			....
			return invokeServiceLocatorMethod(method, args);	
		}


	private Object invokeServiceLocatorMethod(Method method, Object[] args) throws Exception {
			Class<?> serviceLocatorMethodReturnType = getServiceLocatorMethodReturnType(method);
			try {
				String beanName = tryGetBeanName(args);
				Assert.state(beanFactory != null, "No BeanFactory available");
				if (StringUtils.hasLength(beanName)) {
					// Service locator for a specific bean name
					return beanFactory.getBean(beanName, serviceLocatorMethodReturnType);
				}
				else {
					// Service locator for a bean type
					return beanFactory.getBean(serviceLocatorMethodReturnType);
				}
			}
			catch (BeansException ex) {
				if (serviceLocatorExceptionConstructor != null) {
					throw createServiceLocatorException(serviceLocatorExceptionConstructor, ex);
				}
				throw ex;
			}
		}


    

 invoke主要先根据方法参数获得beanName,通过beanFactory获得bean实例,因此,要特别注意,传入工厂方法的参数要与被spring管理的bean的名字一致才行

相关推荐

  1. springboot服务定位模式

    2024-01-25 07:54:01       58 阅读
  2. 设计模式服务定位模式

    2024-01-25 07:54:01       31 阅读
  3. 谈谈springboot工厂模式

    2024-01-25 07:54:01       42 阅读
  4. 基于SpringBoot校园生活服务平台

    2024-01-25 07:54:01       59 阅读
  5. Springboot jar做成Centos中服务

    2024-01-25 07:54:01       44 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-25 07:54:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-25 07:54:01       101 阅读
  3. 在Django里面运行非项目文件

    2024-01-25 07:54:01       82 阅读
  4. Python语言-面向对象

    2024-01-25 07:54:01       91 阅读

热门阅读

  1. 前端页面直接导出Excel方案

    2024-01-25 07:54:01       58 阅读
  2. arm 汇编调用C

    2024-01-25 07:54:01       54 阅读
  3. ssh: connect to host github.com port 22: Connection timed out

    2024-01-25 07:54:01       49 阅读
  4. hadoop 三种运行方式

    2024-01-25 07:54:01       55 阅读
  5. centos下安装mongo C & C++ 驱动

    2024-01-25 07:54:01       56 阅读
  6. MATLAB Fundamentals>>>Fill Missing Values

    2024-01-25 07:54:01       59 阅读
  7. 常用的gpt-4 prompt words收集6

    2024-01-25 07:54:01       42 阅读
  8. 嵌入式Linux:如何进行嵌入式Linux开发?

    2024-01-25 07:54:01       54 阅读
  9. ORACLE数据导出工具

    2024-01-25 07:54:01       46 阅读