개요
SPI의 전체 이름은 서비스 공급자 인터페이스로, 프레임워크의 확장 및 교체 구성 요소를 시작하는 데 사용할 수 있습니다.
핵심은 인터페이스 구현 + 전략 모드 + 구성 파일을 사용하여 구현 클래스의 동적 로딩을 달성하는 것입니다.
특정 용도에는 몇 가지 규칙이 있습니다.
(1) classPath의 META-INF/services/ 아래에 인터페이스의 전체 이름 파일을 생성하도록 규정되어 있습니다.
(2) 이 파일에 인터페이스를 작성합니다. 구현 클래스의 전체 이름(경로 + 파일 이름)입니다. 구현 클래스가 여러 개인 경우 별도의 줄에 작성합니다.
(3) 2를 사용하는 경우 java.util.ServiceLoader의 load(Interface.class)를 이용하여 구현 클래스를 얻어서 사용하시면 됩니다.
인터페이스 구현 클래스에는 매개변수 없는 생성자가 있어야 한다는 점은 주목할 가치가 있습니다.
구현 사례
이 애플리케이션에는 모듈 A와 모듈 B라는 두 개의 모듈이 있습니다. 이 두 모듈 중 모듈 A는 메인 모듈이고 B는 슬레이브 모듈이며 모듈 B는 모듈 A에 종속됩니다. 그러나 현재 모듈 B에 구현된 클래스가 있습니다. 모듈 A는 이 클래스의 함수를 호출해야 하며, 모듈은 더 이상 모듈 B에 의존할 수 없습니다. 이때 디커플링이 필요합니다. 이 구현에서는 SPI를 디커플링 구현에 사용합니다. 구체적인 구현 계획은 다음과 같습니다.
(1) 모듈 A: MyLogAppender에서 새 인터페이스를 만듭니다. 구체적인 구현은 다음과 같습니다.
/** * @author Huang gen(kenfeng) * @description 自定义的appender接口 * @Since 2021/02/21 **/ public interface MyLogAppender { /** * 获取实现的appender * @return 返回新建的appender对象 * */ Appender getAppender(); }
이 인터페이스는 매우 간단하며 어펜더 개체만 반환합니다. 객체의 실제 동작을 위해서는 인터페이스 구현에서 동작이 수행된다.
(2) 모듈 B에 이 인터페이스의 구현을 추가합니다. 구체적인 작업은 다음과 같습니다.
/** * @author Huang gen(kenfeng) * @description 自定义的appender * @Since 2021/02/21 **/ @Component public class MeshLogAppender extends UnsynchronizedAppenderBase<ILoggingEvent> implements MyLogAppender,ApplicationContextAware { private ApplicationContext applicationContext; public MeshLogAppender(){ } @Override public Appender getAppender() { MeshLogAppender meshLogAppender = new MeshLogAppender(); return meshLogAppender; } @Override protected void append(ILoggingEvent iLoggingEvent) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String std = simpleDateFormat.format(new Date(Long.parseLong(String.valueOf(iLoggingEvent.getTimeStamp())))); String log = std + "\t" + iLoggingEvent.getLevel() +"\t"+"--- ["+ iLoggingEvent.getThreadName()+"]\t"+iLoggingEvent.getCallerData()[0]+":\t "+iLoggingEvent.getMessage(); FlowMessage input = new FlowMessage(); MeshFlowService meshFlowService = SandboxSystemServiceFactory.getService(MeshFlowService.class); Map<String, Object> body = new HashMap<>(2); body.put("log",log); input.setTenantCode(DefaultTenant.get()); input.setAppCode("epoch"); input.setFlowCode("log_broadcast"); input.setBody(body); FlowMessage output = meshFlowService.process(input); if(!StringUtils.isEmpty(output.getErrorMessage())){ throw new RuntimeException("发布日志时,广播失败"); } } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } }
이 인터페이스 선언과 인터페이스 구현에는 구현할 몇 가지 작은 트릭이 있습니다. 인터페이스에서는 클래스 획득만 선언되고 특정 메서드는 구현되지 않습니다. 구현 클래스에서는 이 클래스를 인스턴스화하고 새 클래스를 생성하여 반환합니다. 이때 사용자는 이 get 메서드에 따라 구현 클래스를 가져온 다음 구현 클래스에 대해 몇 가지 작업을 수행할 수 있습니다. 이러한 방식으로 작성하면 다음과 같은 두 가지 이점을 얻을 수 있습니다. i. 코드가 더 간결해지고, 인터페이스 코드가 간단하고 이해하기 쉽습니다. ii. 사용자가 이를 사용할 때 일부 매개변수를 삽입할 수 있습니다. get 메소드에 직접 주입할 수 있습니다.
(3) 구현 클래스가 있는 폴더, 즉 sandbox-app-epoch-starter에 구성 파일을 추가합니다. 구성 파일의 기본 경로는 resources/META-INF/services/입니다. 폴더 새 질문을 생성합니다. 파일 이름은 인터페이스의 경로이고 내용은 구현 클래스의 경로입니다. 이를 통해 인터페이스-->구현 클래스 매핑을 구현할 수 있습니다.
위 그림과 같이 파일 이름은 com.alibaba.halo.sandbox.app.util.MyLogAppender
파일 내용은 com.alibaba.lattice2.epoch.util.MeshLogAppender
The 원칙은 사용자가 인터페이스를 사용할 때 프로젝트 아래의 모든 파일을 검색하여 파일 이름 com.alibaba.halo.sandbox.app.util.MyLogAppender를 찾은 다음 해당 구현 클래스를 기반으로 검색한다는 것입니다. content
(4) A에서는 인터페이스를 직접 사용하여 호출할 수 있습니다. 구체적인 구현은 다음과 같습니다.
ServiceLoader<MyLogAppender> myLoaderInterfaceServiceLoader = ServiceLoader.load(MyLogAppender.class); Iterator<MyLogAppender> myLoaderInterfaceIterator = myLoaderInterfaceServiceLoader.iterator(); while (myLoaderInterfaceIterator.hasNext()){ MyLogAppender myLoaderInterface = myLoaderInterfaceIterator.next(); Appender newAppender = myLoaderInterface.getAppender(); newAppender.setName("application"); newAppender.setContext(loggerContext); newAppender.start(); rootLogger.addAppender(newAppender); }
위에서 볼 수 있듯이 MyLogAppender 인터페이스를 직접 호출할 수 있으며, 얻은 Appender를 사용합니다. 이 인터페이스를 통해 값을 직접 할당합니다.
장점과 단점
장점: 코드의 분리가 가능
단점은 구현 클래스가 여러 개인 경우 특정 매개변수나 플래그를 통해서는 인스턴스를 얻을 수 없고 순회를 통해서만 인스턴스를 얻을 수 있으며, 구현할 수 없습니다. 지연 로딩
위 내용은 SPI를 사용하여 Java에서 디커플링을 달성하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于结构化数据处理开源库SPL的相关问题,下面就一起来看一下java下理想的结构化数据处理类库,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于PriorityQueue优先级队列的相关知识,Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于java锁的相关问题,包括了独占锁、悲观锁、乐观锁、共享锁等等内容,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于多线程的相关问题,包括了线程安装、线程加锁与线程不安全的原因、线程安全的标准类等等内容,希望对大家有帮助。

本篇文章给大家带来了关于Java的相关知识,其中主要介绍了关于关键字中this和super的相关问题,以及他们的一些区别,下面一起来看一下,希望对大家有帮助。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于枚举的相关问题,包括了枚举的基本操作、集合类对枚举的支持等等内容,下面一起来看一下,希望对大家有帮助。

封装是一种信息隐藏技术,是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法;封装可以被认为是一个保护屏障,防止指定类的代码和数据被外部类定义的代码随机访问。封装可以通过关键字private,protected和public实现。

本篇文章给大家带来了关于java的相关知识,其中主要介绍了关于设计模式的相关问题,主要将装饰器模式的相关内容,指在不改变现有对象结构的情况下,动态地给该对象增加一些职责的模式,希望对大家有帮助。


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

DVWA
DVWA(Damn Vulnerable Web App)는 매우 취약한 PHP/MySQL 웹 애플리케이션입니다. 주요 목표는 보안 전문가가 법적 환경에서 자신의 기술과 도구를 테스트하고, 웹 개발자가 웹 응용 프로그램 보안 프로세스를 더 잘 이해할 수 있도록 돕고, 교사/학생이 교실 환경 웹 응용 프로그램에서 가르치고 배울 수 있도록 돕는 것입니다. 보안. DVWA의 목표는 다양한 난이도의 간단하고 간단한 인터페이스를 통해 가장 일반적인 웹 취약점 중 일부를 연습하는 것입니다. 이 소프트웨어는

SublimeText3 영어 버전
권장 사항: Win 버전, 코드 프롬프트 지원!

에디트플러스 중국어 크랙 버전
작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전
