1. @Import는 일반 클래스를 소개합니다.
@Import 주석을 사용하면 일반 클래스를 Bean으로 정의할 수 있습니다. @SpringBootApplication(시작 클래스), @Configuration(구성 클래스), @Component(컴포넌트 클래스)에 해당하는 클래스에 @Import를 추가할 수 있습니다.
참고: @RestController, @Service, @Repository는 모두 @Component에 속합니다
@SpringBootApplication @Import(ImportBean.class) // 通过@Import注解把ImportBean添加到IOC容器里面去 public class MyBatisApplication { public static void main(String[] args) { SpringApplication.run(MyBatisApplication.class, args); } }
2. @Import는 구성 클래스(@Configuration에 의해 수정된 클래스)를 도입합니다.
@Import 외에도 일반 클래스가 가능합니다. Bean으로 정의된 @Import는 @Configuration에 의해 수정된 클래스(구성 클래스 소개)를 도입하여 구성 클래스를 적용할 수도 있습니다(구성 클래스 아래의 모든 Bean이 IOC 컨테이너에 추가됨). 스타터를 사용자 정의할 때 자주 사용됩니다.
구성 클래스가 표준 SpringBoot 패키지 구조(SpringBootApplication 시작 클래스 패키지의 루트 디렉터리)에 있는 경우. Spring Boot는 구성 클래스 가져오기를 자동으로 처리하므로 @Import 주석을 수동으로 사용할 필요가 없습니다. 일반적으로 이러한 상황은 @Configuration 구성 클래스가 표준 Spring Boot 패키지 구조 외부에 있을 때 적용됩니다. 그래서 스타터를 커스터마이징할 때 일반적으로 사용됩니다.
@Configuration(proxyBeanMethods = false) @Import({ // import了两个哈 XXXDataConfiguration.XXXPartOneConfiguration.class, XXXDataConfiguration.XXXPartTwoConfiguration.class }) public class XXXDataAutoConfiguration { } public class XXXDataConfiguration { @Configuration(proxyBeanMethods = false) static class XXXPartOneConfiguration { @Bean @ConditionalOnMissingBean public BeanForIoc beanForIoc() { return new BeanForIoc(); } } @Configuration(proxyBeanMethods = false) static class XXXPartTwoConfiguration { /** * 省略了@Bean的使用 */ } }
3. @Import는 ImportSelector의 구현 클래스를 소개합니다
@Import는 ImportSelector의 구현 클래스를 소개하고 ImportSelector 인터페이스의 selectImports() 메서드에서 반환된 클래스 이름을 빈으로 정의할 수도 있습니다. selectImports() 메소드의 AnnotationMetadata 매개변수에 주목하세요. 이 매개변수를 통해 @Import 주석이 붙은 클래스에 대한 다양한 정보를 얻을 수 있습니다. 이는 매개변수를 전달하는 데 특히 유용합니다. SpringBoot의 자동 구성과 @EnableXXX 주석은 별도로 존재합니다.
public interface ImportSelector { /** * 用于指定需要注册为bean的Class名称 * 当在@Configuration标注的Class上使用@Import引入了一个ImportSelector实现类后,会把实现类中返回的Class名称都定义为bean。 * * 通过其参数AnnotationMetadata importingClassMetadata可以获取到@Import标注的Class的各种信息, * 包括其Class名称,实现的接口名称、父类名称、添加的其它注解等信息,通过这些额外的信息可以辅助我们选择需要定义为Spring bean的Class名称 */ String[] selectImports(AnnotationMetadata importingClassMetadata); }
@Import가 도입한 ImportSelector의 구현 클래스 사용과 관련하여 몇 가지 간단한 사용 시나리오를 살펴보겠습니다(실제 개발은 확실히 이보다 더 복잡합니다).
3.1 정적 가져오기 시나리오(알려진 클래스 주입)
정적 시나리오(알려진 클래스 주입), 다음 예제와 같이 ImportSelector 클래스를 구현하여 빈으로 정의해야 하는 클래스를 직접 반환하는 것은 매우 간단합니다. . EnableXXX 주석을 추가하고 XXXConfigurationSelector를 통해 알려진 클래스 XXX를 삽입해 보겠습니다.
/** * XXXConfigurationSelector一定要配合@Import使用 */ public class XXXConfigurationSelector implements ImportSelector { @Override @NonNull public String[] selectImports(@NonNull AnnotationMetadata importingClassMetadata) { // 把XXX对应的类,定义为Bean return new String[]{XXX.class.getName()}; } } /** * 注意 @Import(XXXConfigurationSelector.class) */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(XXXConfigurationSelector.class) public @interface EnableXXX { } @SpringBootApplication @EnableXXX // 使之生效 public class MyBatisApplication { public static void main(String[] args) { SpringApplication.run(MyBatisApplication.class, args); } }
3.2 동적 가져오기 시나리오(지정된 조건으로 클래스 주입)
이러한 기능을 만들려면 지정된 패키지 경로에 HelloService 인터페이스를 구현하는 모든 클래스를 IOC 컨테이너에 빈으로 추가해야 합니다. @ComponentScan 주석은 경로를 지정하는 데 사용됩니다. 구체적인 구현은 다음과 같습니다.
public interface HelloService { void function(); } public class DynamicSelectImport implements ImportSelector { /** * DynamicSelectImport需要配合@Import()注解使用 * <p> * 通过其参数AnnotationMetadata importingClassMetadata可以获取到@Import标注的Class的各种信息, * 包括其Class名称,实现的接口名称、父类名称、添加的其它注解等信息,通过这些额外的信息可以辅助我们选择需要定义为Spring bean的Class名称 */ @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { // 第一步:获取到通过ComponentScan指定的包路径 String[] basePackages = null; // @Import注解对应的类上的ComponentScan注解 if (importingClassMetadata.hasAnnotation(ComponentScan.class.getName())) { Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(ComponentScan.class.getName()); basePackages = (String[]) annotationAttributes.get("basePackages"); } if (basePackages == null || basePackages.length == 0) { //ComponentScan的basePackages默认为空数组 String basePackage = null; try { // @Import注解对应的类的包名 basePackage = Class.forName(importingClassMetadata.getClassName()).getPackage().getName(); } catch (ClassNotFoundException e) { e.printStackTrace(); } basePackages = new String[]{basePackage}; } // 第er步,知道指定包路径下所有实现了HelloService接口的类(ClassPathScanningCandidateComponentProvider的使用) ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); TypeFilter helloServiceFilter = new AssignableTypeFilter(HelloService.class); scanner.addIncludeFilter(helloServiceFilter); Set<String> classes = new HashSet<>(); for (String basePackage : basePackages) { scanner.findCandidateComponents(basePackage).forEach(beanDefinition -> classes.add(beanDefinition.getBeanClassName())); } // 第三步,返回添加到IOC容器里面去 return classes.toArray(new String[0]); } } @Configuration @ComponentScan("com.tuacy.collect.mybatis") // 指定路径 @Import(DynamicSelectImport.class) public class DynamicSelectConfig { }
4. @Import는 ImportBeanDefinitionRegistrar의 구현 클래스를 소개합니다.
@Import는 ImportBeanDefinitionRegistrar의 구현 클래스를 소개합니다. 일반적으로 Bean을 동적으로 등록하는 데 사용됩니다. 가장 중요한 것은 이러한 BeanDefinition을 추가로 수정하거나 향상시킬 수도 있다는 것입니다. 우리가 자주 사용하는 mybatis @MapperScan은 이런 방식으로 구현됩니다. /**
* ImportBeanDefinitionRegistrar,我们一般会实现ImportBeanDefinitionRegistrar类,然后配合一个自定义的注解一起使用。而且在注解类上@Import我们的这个实现类。
* 通过自定义注解的配置,拿到注解的一些元数据。然后在ImportBeanDefinitionRegistrar的实现类里面做相应的逻辑处理,比如把自定义注解标记的类添加到Spring IOC容器里面去。
*/
public interface ImportBeanDefinitionRegistrar {
/**
* 根据注解的给定注释元数据,根据需要注册bean定义
* @param importingClassMetadata 可以拿到@Import的这个class的Annotation Metadata
* @param registry BeanDefinitionRegistry 就可以拿到目前所有注册的BeanDefinition,然后可以对这些BeanDefinition进行额外的修改或增强。
*/
void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);
}
@Import에서 소개한 ImportBeanDefinitionRegistrar 사용과 관련하여 모든 분들이 mybatis의 @MapperScan 처리 소스 코드를 살펴보는 것이 좋습니다. 매우 흥미로운. 또한 ImportBeanDefinitionRegistrar의 사용을 모든 사람이 직관적으로 볼 수 있도록 매우 간단한 예를 제공합니다. 예를 들어 지정된 패키지 경로에 BeanIoc 주석이 있는 모든 클래스를 빈으로 등록하려고 합니다.
/**
* 我们会把添加了该注解的类作为bean
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface BeanIoc {
}
/**
* 定义包路径。(指定包下所有添加了BeanIoc注解的类作为bean)
* 注意这里 @Import(BeanIocScannerRegister.class) 的使用
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(BeanIocScannerRegister.class)
public @interface BeanIocScan {
String[] basePackages() default "";
}
/**
* 搜索指定包下所有添加了BeanIoc注解的类,并且把这些类添加到ioc容器里面去
*/
public class BeanIocScannerRegister implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {
private final static String PACKAGE_NAME_KEY = "basePackages";
private ResourceLoader resourceLoader;
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
//1. 从BeanIocScan注解获取到我们要搜索的包路径
AnnotationAttributes annoAttrs = AnnotationAttributes.fromMap(annotationMetadata.getAnnotationAttributes(BeanIocScan.class.getName()));
if (annoAttrs == null || annoAttrs.isEmpty()) {
return;
}
String[] basePackages = (String[]) annoAttrs.get(PACKAGE_NAME_KEY);
// 2. 找到指定包路径下所有添加了BeanIoc注解的类,并且把这些类添加到IOC容器里面去
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(beanDefinitionRegistry, false);
scanner.setResourceLoader(resourceLoader);
scanner.addIncludeFilter(new AnnotationTypeFilter(BeanIoc.class));
scanner.scan(basePackages);
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
/**
* 使用,使BeanIocScan生效
*/
@Configuration
@BeanIocScan(basePackages = "com.tuacy.collect.mybatis")
public class BeanIocScanConfig {
}
위 내용은 SpringBoot에서 @Import 주석을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

신흥 기술은 위협을 일으키고 Java의 플랫폼 독립성을 향상시킵니다. 1) Docker와 같은 클라우드 컴퓨팅 및 컨테이너화 기술은 Java의 플랫폼 독립성을 향상 시키지만 다양한 클라우드 환경에 적응하도록 최적화되어야합니다. 2) WebAssembly는 Graalvm을 통해 Java 코드를 컴파일하여 플랫폼 독립성을 확장하지만 성능을 위해 다른 언어와 경쟁해야합니다.

다른 JVM 구현은 플랫폼 독립성을 제공 할 수 있지만 성능은 약간 다릅니다. 1. OracleHotspot 및 OpenJDKJVM 플랫폼 독립성에서 유사하게 수행되지만 OpenJDK에는 추가 구성이 필요할 수 있습니다. 2. IBMJ9JVM은 특정 운영 체제에서 최적화를 수행합니다. 3. Graalvm은 여러 언어를 지원하며 추가 구성이 필요합니다. 4. AzulzingJVM에는 특정 플랫폼 조정이 필요합니다.

플랫폼 독립성은 여러 운영 체제에서 동일한 코드 세트를 실행하여 개발 비용을 줄이고 개발 시간을 단축시킵니다. 구체적으로, 그것은 다음과 같이 나타납니다. 1. 개발 시간을 줄이면 하나의 코드 세트 만 필요합니다. 2. 유지 보수 비용을 줄이고 테스트 프로세스를 통합합니다. 3. 배포 프로세스를 단순화하기위한 빠른 반복 및 팀 협업.

Java'SplatformIndenceFacilitatesCodereScoderEByWatHeAveringByTeCodetOrunonAnyPlatformwitHajvm.1) DevelopersCanwriteCodeOnceforConsentEStentBehaviorAcRossPlatforms.2) MAINTENDUCEDSCODEDOES.3) LIBRRIESASHSCORAREDERSCRAPERAREDERSPROJ

Java 응용 프로그램의 플랫폼 별 문제를 해결하려면 다음 단계를 수행 할 수 있습니다. 1. Java의 시스템 클래스를 사용하여 시스템 속성을보고 실행중인 환경을 이해합니다. 2. 파일 클래스 또는 java.nio.file 패키지를 사용하여 파일 경로를 처리하십시오. 3. 운영 체제 조건에 따라 로컬 라이브러리를로드하십시오. 4. visualVM 또는 JProfiler를 사용하여 크로스 플랫폼 성능을 최적화하십시오. 5. 테스트 환경이 Docker Containerization을 통해 생산 환경과 일치하는지 확인하십시오. 6. githubactions를 사용하여 여러 플랫폼에서 자동 테스트를 수행하십시오. 이러한 방법은 Java 응용 프로그램에서 플랫폼 별 문제를 효과적으로 해결하는 데 도움이됩니다.

클래스 로더는 통합 클래스 파일 형식, 동적로드, 부모 위임 모델 및 플랫폼 독립적 인 바이트 코드를 통해 다른 플랫폼에서 Java 프로그램의 일관성과 호환성을 보장하고 플랫폼 독립성을 달성합니다.

Java 컴파일러가 생성 한 코드는 플랫폼 독립적이지만 궁극적으로 실행되는 코드는 플랫폼 별입니다. 1. Java 소스 코드는 플랫폼 독립적 인 바이트 코드로 컴파일됩니다. 2. JVM은 바이트 코드를 특정 플랫폼의 기계 코드로 변환하여 크로스 플랫폼 작동을 보장하지만 성능이 다를 수 있습니다.

멀티 스레딩은 프로그램 대응 성과 리소스 활용을 향상시키고 복잡한 동시 작업을 처리 할 수 있기 때문에 현대 프로그래밍에서 중요합니다. JVM은 스레드 매핑, 스케줄링 메커니즘 및 동기화 잠금 메커니즘을 통해 다양한 운영 체제에서 멀티 스레드의 일관성과 효율성을 보장합니다.


핫 AI 도구

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

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

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

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

WebStorm Mac 버전
유용한 JavaScript 개발 도구

SublimeText3 Linux 새 버전
SublimeText3 Linux 최신 버전

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기
