Статья размещена наGitHub, вы можете зайти на GitHub, чтобы читать и читать, а боссы могут прийти в Star! Найдите и подпишитесь на общедоступный номер WeChat и получите предложение на получение различных учебных материалов!
SpringDI (внедрение зависимостей)
1. Обзор DI
Внедрение зависимостей — это внедрение зависимостей, или сокращенно DI..
Проще говоря, когда Spring создает объект, присвоение значений его свойствам называется внедрением зависимостей.
Образно говоря, зависимости между компонентами определяются контейнером во время выполнения, то есть контейнер динамически внедряет зависимость в компонент.
2. Что такое ДИ
2.1 Понять идею DI
После краткого понимания DI (внедрение зависимостей), глядя на слово внедрение зависимостей, мы также можем разделить его в форме IOC (инверсия управления).
Как следует из названия, внедрение зависимостей состоит из двух слов «зависимость» и «внедрение», так что давайте снова проследим за подсказками и проанализируем эти два слова по отдельности!
2.2 Зависимости
Слово зависимость можно разбить на множество элементов. Например, выполнение условия зависимости должно бытьдва объекта,кто от кого зависит,что объект зависит от другого объекта. Здесь мы можем перечислить эти ситуации в соответствии с этими условиями:
- Что касается того, кто от кого зависит, конечно, приложение зависит от контейнера IOC. Эта зависимость возникает из-за того, что приложение использует внешние ресурсы, необходимые для объектов, предоставляемых контейнером IOC. (Можно понимать как вход, хотя и не так строго!)
2.3 Инъекция
Введенный один раз, может или может быть разделен на множество элементов. Например, инъекцию можно разделить накто колет кому,что было введено. Здесь мы также можем перечислить эти ситуации в соответствии с этими двумя условиями:
- Что касается того, кто кого вводит, IOC в качестве контейнера должен быть внедренным объектом, то есть мы внедряем требуемые объекты в контейнер IOC. Что касается того, что инжектится, то очевидно, что это объекты, ресурсы, данные и т.д., необходимые в нашем проекте. Проще говоря, нам нужны внешние ресурсы, которые можно внедрить в IOC-контейнер, а IOC-контейнер будет реализовывать управляющую инверсию внедряемого объекта!
- IOC должен динамически предоставлять объекту другие необходимые ему объекты во время работы системы. Это достигается с помощью DI (внедрение зависимостей).
3. Инъекционный метод
3.1 Внедрение метода установки
Внедрение метода Setter, для реализации внедрения необходимо только предоставить соответствующий интерфейс метода Setter.Поскольку JavaBeans обычно реализуют методы Setter, внедрение метода Setter также стало одним из наших часто используемых методов внедрения.
3.1.1 Определение JavaBeans
Определите JavaBean и дайте ему метод Setter
package com.mylifes1110.bean;
import java.util.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//Lombok@Data注解提供了Setter方法
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String password;
private String sex;
private Integer age;
private Date bornDate;
private String[] hobbys;
private Set<String> phones;
private List<String> names;
private Map<String, String> countries;
private Properties files;
}
3.1.2 Внедрение различных типов данных
Примечание. Нижний уровень Spring обрабатывает тип даты Date, а формат обработки по умолчанию — «гггг/мм/дд».
<bean id="User" class="com.mylifes1110.bean.User">
<!--注入基本数据类型-->
<property name="id" value="1"/>
<property name="password" value="123456"/>
<property name="sex" value="male"/>
<property name="age" value="18"/>
<!--注入日期类型-->
<property name="bornDate" value="1999/09/09"/>
<!--注入数组类型-->
<property name="hobbys">
<array>
<value>Run</value>
<value>Jump</value>
<value>Climb</value>
</array>
</property>
<!--注入List集合类型-->
<property name="names">
<list>
<value>Ziph</value>
<value>Join</value>
<value>Marry</value>
</list>
</property>
<!--注入Set集合类型-->
<property name="phones">
<set>
<value>110</value>
<value>119</value>
<value>120</value>
</set>
</property>
<!--注入Properties类型-->
<property name="files">
<props>
<prop key="first">One</prop>
<prop key="second">Two</prop>
<prop key="third">Three</prop>
</props>
</property>
<!--注入Map集合类型-->
<property name="countries">
<map>
<entry key="CHINA" value="中国"/>
<entry key="USA" value="美国"/>
<entry key="UK" value="英国"/>
</map>
</property>
</bean>
3.1.3 Внедрение данных собственного типа
Слою службы нужен объект класса реализации уровня Dao, мы можем использовать метод инъекции, чтобы реализовать ассоциацию объектов между слоем службы и слоем Dao.
<bean id="UserDao" class="com.mylifes1110.dao.impl.UserDaoImpl"/>
<bean id="UserService" class="com.mylifes1110.service.impl.UserServiceImpl">
<property name="userDao" ref="UserDao"/>
</bean>
Внедрить созданный объект Bean в другой объект, например объект JavaBean, в качестве свойства другого объекта JavaBean.
<!--次要bean,被作为属性-->
<bean id="address" class="com.mylifes1110.bean.Address">
<property name="position" value="上海市" />
<property name="zipCode" value="100001" />
</bean>
<!--主要bean,操作的主体-->
<bean id="user" class="com.mylifes1110.bean.User">
<!--address属性引用address对象-->
<property name="address" ref="address" />
</bean>
3.2 Внедрение конструктора
Когда объект создается, фабрика Spring присваивает значения свойствам объекта через конструктор. Поскольку некоторые фреймворки или проекты не предоставляют методы Setter для JavaBeans, мы можем использовать их конструкторы для их внедрения. Не говорите мне, что конструктор не предусмотрен! (просто шучу!)
3.2.1 Определение JavaBeans
Определите объект JavaBean и предоставьте для него конструктор
public class Student {
private Integer id;
private String name;
private String sex;
private Integer age;
//Constructors
public Student(Integer id , String name , String sex , Integer age){
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
}
}
3.2.2 Внедрение конструктора
<!--构造注入-->
<bean id="u3" class="com.mylifes1110.bean.Student">
<!-- 除标签名称有变化,其他均和Set注入一致 -->
<constructor-arg name="id" value="1234" />
<constructor-arg name="name" value="tom" />
<constructor-arg name="age" value="20" />
<constructor-arg name="sex" value="male" />
</bean>
3.3 Автоматический впрыск
Нет необходимости указывать в конфигурации, какое свойство присваивать и какое значение присваивать. Spring автоматически ищет bean-компонент на фабрике в соответствии с определенным «принципом» и вводит значение свойства для свойства.
3.3.1 Сцена инъекции
Вставьте объект класса реализации уровня Dao в уровень службы и вызовите метод для проверки
package com.mylifes1110.service.impl;
import com.mylifes1110.bean.User;
import com.mylifes1110.dao.UserDao;
import com.mylifes1110.service.UserService;
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public int insertUser(User user) {
System.out.println("------insertUser and UserService------");
return userDao.insertUser(null);
}
}
3.3.2 Два способа автоматической инъекции
Автоматически вводить значения на основе имени
<bean id="UserDao" class="com.mylifes1110.dao.impl.UserDaoImpl"/>
<!--为UserServiceImpl中的属性基于名称自动注入值-->
<bean id="userService" class="com.mylifes1110.service.impl.userServiceImpl" autowire="byName"/>
</beans>
Автоматически вводить значение на основе типа, судить и автоматически вводить значение в соответствии с реализованным интерфейсом. Если существует слишком много классов реализации, реализующих этот интерфейс, он выберет класс реализации с тем же именем среди многих классов реализации, реализующих этот интерфейс для внедрения. (Теперь по приговору, при неудаче будет инжектиться по имени)
<bean id="userDao" class="com.mylifes1110.dao.UserDaoImpl" />
<!--为UserServiceImpl中的属性基于类型自动注入值-->
<bean id="userService" class="com.mylifes1110.service.impl.UserServiceImpl" autowire="byType"/>
</beans>
3.4 Автоматическое введение аннотаций
Название аннотации | описывать |
---|---|
@Autowired | Автоматический впрыск в зависимости от типа |
@Resource | Автоматическая инъекция на основе имени |
@Qualifier("userDAO") | Определяет идентификатор bean-компонента для автоматического внедрения, обычно используется в сочетании с @Autowired. |
@Value | Вставка данных простого типа (базовые типы данных jdk8 + тип String) |
Используйте автоматическую инъекцию на основе типов для внедрения слоя Dao в слой службы.
@Service
public class UserServiceImpl implements UserService {
@Autowired //注入类型为UserDao的bean
@Qualifier("userDao") //如果有多个类型为UserDao的bean,可以用此注解从中指定一个
private UserDao userDao;
}
Внедрить слой Dao в слой Serivce, используя автоматическую инъекцию на основе имени.
@Service
public class UserServiceImpl implements UserService {
@Resource("userDao") //注入id=“userDao”的bean
private UserDao userDao;
}
Простая инъекция JavaBeans с использованием аннотаций данных простого типа
public class User{
@Value("1") //注入数字
private Integer id;
@Value("Ziph") //注入String
private String name;
}