Learn about IOC's dependency injection

bd2star 2021-01-22 11:27:24
learn ioc dependency injection


Have dreams , Have feelings , Have temperature , Dry cargo is full. ; Pay attention to me .

One 、 Annotation driven IoC

xml drive Of IoC The container uses ClassPathXmlApplicationContext Read xml Inside bean Information

Annotation driven Of IoC The container uses AnnotationConfigApplicationContext Read Java Class bean Information

1. AnnotationConfigApplicationContext Registration and use of

Compared with xml File as driver , Annotation drivers need to specify Configuration class A configuration class can be understood as " amount to " One xml To configure a class, you just need to annotate it @Configuration

@Configuration
public class DemoConfiguration {
}

stay xml In a statement bean The way

<bean id="person" class="com.huodd.bean.Person"></bean>

What is used in the configuration class is @Bean annotation

@Bean
public Person person() {
return new Person();
}

explain : towards IoC The container registers a type of Persion,id by Person Of Bean

The method name represents bean Of id The return value represents the registered bean The type of

@Bean Annotations can also display the declaration of bean Of id Such as @Bean("person1")

2. annotation IoC Initialization of container

public class AnnotationConfigApplication {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(DemoConfiguration.class);
Person person = ctx.getBean(Person.class);
System.out.println(person);
}
}

After operation Person Console print results

com.huodd.bean.Person@55536d9e

3. Component registration and scanning

During the above initialization We are using AnnotationConfigApplicationContext You pass the parameter Class<?>... componentClasses

Look over AnnotationConfigApplicationContext You can also find parameter types that can pass parameters and String... basePackages

This is about Component registration and scanning

Here's a question to think about , If we have too many components to register , Then write these @Bean The workload of the code will also be particularly heavy when it is used , How to solve this problem ?

Spring Give us a few notes , Can help us quickly register the components we need , These annotations are called Pattern annotation (stereotype annotations)

@Component

@Component It can be said that it is the root of all component registration Mark... On the class @Component Represents that the class is registered to IoC In the container as a Bean

@Component
public class Person {
}

If not specified Bean The name of The default rule is " The first letter of the class name is lowercase " above bean The default name will be person

If you want to customize bean The name of Can be in @Component Statement value The value of the can Such as

@Component("person1")
public class Person {
}

stay xml Equivalent to

<bean id="person1" class="com.huodd.bean.Person"/>

@ComponentScan

This is the time If we run the boot class directly obtain Person Of bean object , Will report a mistake NoSuchBeanDefinitionException Why is that ?

Because we just declared the component , And then it just started IoC Containers , In this way, the container is not aware of @Component There is ,

Solution 1:

We need to add a new annotation when we write the configuration class @ComponentScan

The purpose is to tell IoC Containers I'm going to scan which bag has @Component Annotated classes

@Configuration
@ComponentScan("com.huodd.bean")
public class DemoComponentScanConfiguration {
}

notes : If you don't specify a scan path , be By default, scan the package and all subpackages of this class Lower with @Component The components of

The startup class code is as follows :

public class AnnotationConfigApplication {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(DemoComponentScanConfiguration.class);
Person person = ctx.getBean(Person.class);
System.out.println(person);
}
}

Solution 2:

There is no need to write @ComponentScan And directly in AnnotationConfigApplicationContext Method parameter String Type of Packet scan path The code is as follows

public class AnnotationConfigApplication {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext("com.huodd.bean");
Person person = ctx.getBean(Person.class);
System.out.println(person);
}
}

PS: Component scanning is not annotation driven IoC Unique , Actually in xml Driven IoC In mode Component scanning can also be enabled , Only need xml Just declare a label in

<context:component-scan base-package="com.huodd.bean"/>

Here's the thing to notice : If you need to scan multiple paths , You need to write multiple tags That is to say A label can only declare one root package

Component registration supplement

SpringFramework Provides information on the ongoing Web Extension notes for developing three tier architecture : Respectively @Controller@Service@Repository Are you familiar with ?

Represent the The presentation layer The business layer Persistence layer The function of these three annotations is related to @Component Exactly the same as We can see from the source code The bottom layer adds... To these three annotation classes @Component

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
}

such When we are developing a three-tier architecture For the corresponding example ServiceImpl etc. You can mark it directly @Service Wait for comment

@Configuration

@Configuration There are also labels on the bottom @Component

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration { ... }

It can be explained that , The configuration class is not what we think , It's just a configuration , It will also be seen as bean, Also registered to IoC Inside the container

4. Annotation driven and xml Drivers refer to each other

4.1 xml Reference notes

To enable annotation configuration Then register the corresponding configuration class

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- Turn on annotation configuration -->
<context:annotation-config />
<!-- Register configuration class -->
<bean class="com.huodd.config.AnnotationConfigConfiguration"/>
</beans>

4.2 The note quotes XMl

You need to mark... On the configuration class @ImportResource And declare the path to the configuration file

@Configuration
@ImportResource("classpath:annotation/demo-beans.xml")
public class ImportXmlAnnotationConfiguration {
}

Two 、IoC Dependency injection of

1.Setter Attribute injection

Create objects Set property values set go in Then return the object

@Bean
public Person person() {
Person person = new Person();
person.setId(1);
person.setName("PoXing");
person.setAge(18);
return person;
}

xml Medium setter Inject

<bean id="person" class="com.huodd.bean.Person">
<property name="id" value="1"/>
<property name="name" value="PoXing"/>
<property name="age" value="18"/>
</bean>

2. Constructor Injection

Use constructor Injection , Need to be in bean Add a parametric construction method itself , If in Person The construction method of adding parameters in is as follows

public Person(Integer id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}

Annotation driven in , We created bean When injecting properties You need to specify parameter values at the same time

@Bean
public Person person() {
return new Person(1, "PoXing", 18);
}

xml drive Below

<bean id="person" class="com.huodd.bean.Person">
<!--
index: Represents the parameter index of the constructor
value: Represents the corresponding parameter value
-->
<constructor-arg index="0" value="1"/>
<constructor-arg index="1" value="PoXing"/>
<constructor-arg index="2" value="18"/>
</bean>

3. Annotation property injection

Let's start with , Why is there annotation property value injection . Careful little friends may find out What we talked about above Setter Attribute injection Constructor Injection It's like you can only use @Bean Use when annotating , however If it's by tagging @Component Annotation components ( Like our front Person Class marked with @Component annotation ), How to set property values for it , This section is mainly about this part

@Component Property injection under

Here we use Dog Class as a demonstration ( Here I quietly added @Component annotation You should pay attention to yourself Otherwise, it will be wrong )

@Component
public class Dog {
private Integer id;
private String name;
private Integer age;
... Omit Getter、Setter
... Omit toString
}

Here we need to implement annotation property injection , You can mark it directly on the fields to be injected @Value annotation Such as

@Value("1")
private Integer id;
@Value("wangcai")
private String name;
@Value("3")
private Integer age;

The startup class code is as follows

public class DiApplication {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext("com.huodd.bean");
Dog dog = ctx.getBean(Dog.class);
System.out.println(dog);
}
}

Console print results

Dog{id=1, name='wangcai', age=3}

External profile (@PropertySource)

Here is mainly to solve the above problems @Value In the injection We fixed the attribute value directly and wrote it dead , If you want to modify I have to go Java Code to modify , It's not in line with the development specifications ,

SpringFramework It's a new annotation for us @PropertySource It is mainly used to import external configuration files

  1. Here we create a dog.properties
dog.id=1
dog.name=wangcai
dog.age=3
  1. Import profile
@PropertySource("classpath:di/dog.properties")
@ComponentScan("com.huodd.bean")
@Configuration
public class DemoComponentScanConfiguration {
}
  1. Dog Class here @Value Need to cooperate with Place holder To get properties What's in the configuration file
@Value("${dog.id}")
private Integer id;
@Value("${dog.name}")
private String name;
@Value("${dog.age}")
private Integer age;
  1. Modify the startup class
public class DiApplication {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(DemoComponentScanConfiguration.class);
Dog dog = ctx.getBean(Dog.class);
System.out.println(dog);
}
}

The results of console printing are as follows

Dog{id=1, name='wangcai', age=3}

At this point, the properties of the configuration file have been injected successfully

4. Automatic injection

stay xml There's... In the pattern ref attribute You can put a bean Inject into another bean in , It's also possible in annotation mode

@Autowired

to Dog Of bean In the injection Person Of Bean ( namely to dog Designate its owner )

Method 1 → Mark... On attributes

@Component
public class Dog {
// ......
@Autowired
private Person person;
}

Method 2 → Using constructor Injection

@Component
public class Dog {
// ......
private Person person;
@Autowired
public Dog(Person person) {
this.person = person;
}
}

Method 3 → Use setter Methods to inject

@Component
public class Dog {
// ......
private Person person;
@Autowired
public void setPerson(Person person) {
this.person = person;
}
}

JSR250 Under the norm @Resource

@Resource It's also an annotation for property injection

It is associated with @Autowired Is the difference between the :

  • @Autowired Is in accordance with the type Inject
  • @Resource Is in accordance with the Property name ( That is to say bean The name of ) Inject

@Resource Annotations are equivalent to annotations @Autowired and @Qualifier

@Qualifier Here is a brief explanation , For a given bean The name of , If there are multiple identical bean, and bean The names are different , We can use @Autowired To configure @Qualifier annotation

Such as : The following shows that Dog The owner of class injection Bean It's called xiaowang Of , There may be more than one in the current container master bean object such as xiaoli、xiaoming ....

@Component
public class Dog {
// ......
@Autowired
@Qualifier("xiaowang")
private Person person;
}

Next, if you use @Resource It can be more convenient The code is as follows

@Component
public class Dog {
// ......
@Resource(name="xiaowang")
private Person person;
}

JSR330 Under the norm @Inject

@Inject So are annotations Inject by type , And @Autowire The strategy is the same , But if you want to use @Inject Additional import dependencies are required

<!-- jsr330 -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>

The following usage is similar to SpringFramework Native @Autowire + @Qualifier It's the same

@Component
public class Dog {
@Inject // Equate to @Autowired
@Named("xiaowang") // Equate to @Qualifier
private Person person;

It is associated with @Autowired Is the difference between the :

  • @Autowired The package is org.springframework.beans.factory.annotation.Autowired That is to say SpringFramework Provided
  • @Inject The package is javax.inject.Inject Belong to JSR The specification of That is to say, if you don't use SpringFramework You can use this annotation

5. Complex type injection

Array Inject

<property name="names">
<array>
<value>PoXing</value>
<value>LaoWang</value>
</array>
</property>

List Inject

<property name="tels">
<list>
<value>13000000000</value>
<value>13000000001</value>
</list>
</property>

Set Inject -

<!-- It's been announced in advance. OK Dog -->
<bean id="wangcai" class="com.huodd.bean.ext.Dog"/>
---
<property name="dogs">
<set>
<bean class="com.huodd.bean.Dog"/>
<ref bean="wangcai"/>
</set>
</property>

Map Inject

<property name="homesMap">
<map>
<entry key="1" value="main">
<ref bean="myHome1" />
</entry>
<entry key="2" value="other">
<ref bean="myHome2" />
</entry>
</map>
</property>

Properties Inject

<property name="props">
<props>
<prop key="sex"> male </prop>
<prop key="age">18</prop>
</props>
</property>

Interview questions

1.@Autowired What is the injection principle ?

  1. Take the type corresponding to the attribute first , Go to IoC Find the corresponding... In the container Bean
  2. If not found Direct selling NoUniqueBeanDefinitionException abnormal
  3. If you find one Go straight back to
  4. If you find more than one of the same type bean Take the attribute name to deal with these multiple bean Of id Contrast
  5. If there are multiple or none It will be thrown out. NoUniqueBeanDefinitionException abnormal
  6. If only one Go straight back to

2. What are the ways of dependency injection , What's the difference

Injection mode Whether the injected object can be changed Whether to rely on IOC Framework of the API Use scenarios
Constructor Injection immutable no Immutable fixed injection
Parameter injection immutable no In the annotation configuration class @Bean Methods registration bean
Attribute injection ( Annotation property injection ) immutable yes ( You can only inject intrusively by annotating ) Usually used for immutable fixed injection
setter Inject variable no Injection of optional attributes

3. Auto injected annotation comparison

annotation Injection mode Do you support @Primary source Bean When it doesn't exist
@Autowired Inject... According to type yes SpringFramework Primary annotation Can be specified required=false To avoid injection failure
@Resource Inject... By name yes JSR250 standard The specified... Does not exist in the container Bean It throws an exception
@Inject Inject... According to type yes JSR330 standard ( Need guidance jar package ) The specified... Does not exist in the container Bean It throws an exception

@Qualifier : If the marked member / Method found multiple of the same type when injecting by type Bean , Will be declared according to the annotation name Look for specific bean

@Primary : If there are more than one of the same type Bean Also register to IOC In the container , Use “ Inject... According to type ” Annotation will be injected when the annotation of @Primary Annotated bean The default policy

4. What are the advantages and disadvantages of using dependency injection

  • Dependency injection as IOC One of the ways to realize , The purpose is to decoupling , We don't need to go straight to new Those dependent class objects can be directly retrieved from the container for use , If a component has multiple levels of dependencies , Dependency injection can simplify the relationship of these dependencies .
  • Object dependent Configurable : adopt xml Or annotation statement , You can specify and adjust the object that the component injects , With the help of Java The polymorphic characteristics of , The replacement of dependency injected objects can be completed without mass modification

I am a Baoxing, The best time to start something , Or ten years ago , Or now . Thank you for give the thumbs-up Collection and Comment on

版权声明
本文为[bd2star]所创,转载请带上原文链接,感谢
https://javamana.com/2021/01/20210122105838244c.html

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云