IoCコンテナ(2):@Autowired,構成部品スキャン,空スキャン
5. @Autowired
必要な依存オブジェクトのタイプ(Type)に対応する空を検索して入力します.
@Autowired
要求
使用可能な場所
public class BookRepository {
}
@Service
public class BookService {
BookRepository bookRepository;
@Autowired(required = False)
public void setBookRepository(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
}
境遇-空の名前を試します.
1.同じ名前の空が見つかった場合は、その空を使用します.
2.同じ名前が見つからないと失敗する
@Repository @Primary
public class MyBookRepository implements BookRepository{
}
@Repository
public class MyBookRepository2 implements BookRepository{
}
@Primary Anotation付きMyBook Repositoryを使用します.@Service
public class BookService {
@Autowired
List<BookRepository> bookRepositories;
public void printBookRepository(
this.bookRepositories.forEach(System.out::println);
}
}
@Service
public class BookService {
@Autowired @Qualifier("myBookRepository")
BookRepository BookRepository;
public void printBookRepository(){
System.out.println(bookRepository.getClass());
}
}
または、フィールド名を表示し、フィールド名と同じタイプと名前の空を入力します.@Service
public class BookService {
@Autowired
BookRepository myBookRepository;
public void printBookRepository(){
System.out.println(mybookRepository.getClass());
}
}
動作原理BeanPostProcessor
というアイドルライフサイクルインタフェースによって処理される.空きライフサイクルでは、空きインスタンスを作成し、初期化中に(空きがある)ライフサイクル間のコールバックを処理し、そのインスタンスの前または後にbeanPostProcessorライフサイクルインタフェースを使用して新しく作成した空きインスタンスを変更できます.@Service
public class BookService {
@Autowired @Qualifier("myBookRepository")
BookRepository myBookRepository;
@PostConstruct
public void setUp(){
System.out.println(myBookRepository.getClass());
}
}
@Service
public class BookService implements InitializingBean {
@Autowired @Qualifier("myBookRepository")
BookRepository myBookRepository;
@Override
public void afterPropertiesSet() throws Exception {
}
}
空の工場ライフサイクルインタフェースと方法https://velog.io/@jsj3282/IoC-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EC%99%80-ApplicationContext-BeanFactory
さらに、springは、springが提供する@Autowiredおよび@Valueおよび@Injectのプレゼンテーションを
AutowiredAnnotationBeanPostProcessor extends BeanPostProcessor
を使用して処理することもできる.(P u n P o s t P o s t P o s s P o f o r einInitializationメソッドセクションで処理)検証方法
@Component
public class MyRunner implements ApplicationRunner {
@Autowired
ApplicationContext applicationContext;
/*
@Autowired
AutowiredAnnotationBeanPostProcessor processor;
*/
@Override
public void run(ApplicationArguments args) throws Exception {
AutowiredAnnotationBeanPostProcessor bean = applicationContext.getBean(AutowiredAnnotationBeanPostProcessor.class);
System.out.println(bean);
}
}
6.@Componentと構成部品スキャン
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
/**
* Alias for {@link #basePackages}.
* <p>Allows for more concise annotation declarations if no other attributes
* are needed — for example, {@code @ComponentScan("org.my.pkg")}
* instead of {@code @ComponentScan(basePackages = "org.my.pkg")}.
*/
@AliasFor("basePackages")
String[] value() default {};
/**
* Base packages to scan for annotated components.
* <p>{@link #value} is an alias for (and mutually exclusive with) this
* attribute.
* <p>Use {@link #basePackageClasses} for a type-safe alternative to
* String-based package names.
*/
@AliasFor("value")
String[] basePackages() default {};
/**
* Type-safe alternative to {@link #basePackages} for specifying the packages
* to scan for annotated components. The package of each class specified will be scanned.
* <p>Consider creating a special no-op marker class or interface in each package
* that serves no purpose other than being referenced by this attribute.
*/
Class<?>[] basePackageClasses() default {};
構成部品スキャンのキー機能スプリングの実行時間を短縮したい場合->スプリング5から導入されたギャップを使用して空の登録を行う場合(反射やcglibなどのエージェントは使用しないため)
public static void main(String[] args) {
new SpringApplicationBuilder()
.sources(Demospring51Application.class)
.initializers((ApplicationContextInitializer<GenericApplicationContext>) applicationContext -> {
applicationContext.registerBean(MyBean.class);
})
.run(args);
}
@SpringBootApplication
public class Springtest2Application {
public static void main(String[] args) {
// SpringApplication.run(Springtest2Application.class, args);
var app = new SpringApplication(Springtest2Application.class);
app.addInitializers(new ApplicationContextInitializer<GenericApplicationContext>() {
@Override
public void initialize(GenericApplicationContext ctx) {
ctx.registerBean(MyService.class); // 컴포넌트 스캔 밖에 있는 클래스 빈으로 등록
}
});
}
}
@SpringBootApplication
public class Springtest2Application {
@Autowired
MyService myService;
public static void main(String[] args) {
// SpringApplication.run(Springtest2Application.class, args);
var app = new SpringApplication(Springtest2Application.class);
app.addInitializers((ApplicationContextInitializer<GenericApplicationContext>) ctx -> {
ctx.registerBean(MyService.class); // 컴포넌트 스캔 밖에 있는 클래스 빈으로 등록
}
}
あるいは、機能インタフェースを使用してもよい.@SpringBootApplication
public class Springtest2Application {
@Autowired
MyService myService;
public static void main(String[] args) {
// SpringApplication.run(Springtest2Application.class, args);
var app = new SpringApplication(Springtest2Application.class);
/*
app.addInitializers(new ApplicationContextInitializer<GenericApplicationContext>() {
@Override
public void initialize(GenericApplicationContext ctx) {
ctx.registerBean(MyService.class);
}
});
*/
app.addInitializers((ApplicationContextInitializer<GenericApplicationContext>) ctx -> {
ctx.registerBean(MyService.class);
ctx.registerBean(ApplicationRunner.class, () -> args1 -> System.out.println("Functional Bean Definition!!"));
// ctx.registerBean(ApplicationRunner.class, new Supplier<ApplicationRunner>() {
// @Override
// public ApplicationRunner get() {
// return args1 -> System.out.println("Functinal Bean Definition!!");
// }
// @Override
// public ApplicationRunner get() {
// return new ApplicationRunner() {
// @Override
// public void run(ApplicationArguments args) throws Exception {
// System.out.println("Functional Bean Definiton!!");
// }
// };
// }
// });
});
app.run(args);
}
}
@ComponentScanがパンクを使用して1つ1つ空の登録を放棄するよりも、@Configuration+@Beanで登録した@Beanを使用します.動作原理
7.空鏡
スキャン
- Request
- Session
- WebSocket
- ...
@Component @Scope(value = "prototype")
public class Proto {
@Autowired
Single single;
}
単音位が原型位を参照すると?@Component
public class Single {
@Autowired
private Proto proto;
public Proto getProto() {
return proto;
}
}
- scoped-proxy
- Object-Provider
-プロバイダ(標準)
@Component @Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class Proto {
@Autowired
Single single;
}
cglibraryというサードパーティ製ツールを使用して、クラスベースのエージェントを作成します.もともとJavaはインタフェースベースのエージェントしか作成できませんでした.Proxyも同じタイプなので注入できます.また、proxyを使う以外にも、他の方法があります.
@Component
public class Single {
@Autowired
private ObjectProvider<Proto> proto;
public Proto getProto() {
return proto.getIfAvailable();
}
}
モノトーンオブジェクトを使用する際の注意点@Component
public class Single {
@Autowired
private Proto proto;
// 쓰레드 세이프하다고 보장받을 수 없음(공유되는 bean)
int value = 0;
public Proto getProto() {
return proto;
}
}
リファレンスReference
この問題について(IoCコンテナ(2):@Autowired,構成部品スキャン,空スキャン), 我々は、より多くの情報をここで見つけました https://velog.io/@jsj3282/IoC-컨테이너-2テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol