предисловие
Во второй части Spring я в основном объясняю проблему использования контейнера IOC для создания объектов в модуле Spring Core.Используйте контейнер IOC для разрешения зависимостей между объектами!
Просмотрите предыдущие зависимости объекта
Давайте посмотрим на нашу предыдущую историю зависимостей объектов.
прямой новый объект
- Вначале мы напрямую присваиваем новый объект свойству userDao службы...
class UserService{
UserDao userDao = new UserDao();
}
Напишите DaoFactory и используйте строки для поддержки зависимостей
-
Позже мы обнаружили, что уровень сервиса тесно связан с уровнем dao.Мы написали DaoFactory, и на сервисном уровне, пока передается строка, может быть создан соответствующий объект дао-слоя.
-
DaoFactory
public class DaoFactory {
private static final DaoFactory factory = new DaoFactory();
private DaoFactory(){}
public static DaoFactory getInstance(){
return factory;
}
public <T> T createDao(String className,Class<T> clazz){
try{
T t = (T) Class.forName(className).newInstance();
return t;
}catch (Exception e) {
throw new RuntimeException(e);
}
}
}
- serivce
private CategoryDao categoryDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.CategoryDAOImpl", CategoryDao.class);
private BookDao bookDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.BookDaoImpl", BookDao.class);
private UserDao userDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.UserDaoImpl", UserDao.class);
private OrderDao orderDao = DaoFactory.getInstance().createDao("zhongfucheng.dao.impl.OrderDaoImpl", OrderDao.class);
DaoFactory читает файлы конфигурации
-
Позже мы обнаружили, чтоЧтобы изменить класс реализации Dao, вам все равно придется изменить исходный код сервисного уровня.Ах..Итак, мы читаем конфигурационный файл о daoImpl в DaoFactory и создаем объекты в соответствии с конфигурационным файлом, чтобы созданный daoImpl был прозрачным для сервисного уровня.
-
DaoFactory
public class DaoFactory {
private UserDao userdao = null;
private DaoFactory(){
try{
InputStream in = DaoFactory.class.getClassLoader().getResourceAsStream("dao.properties");
Properties prop = new Properties();
prop.load(in);
String daoClassName = prop.getProperty("userdao");
userdao = (UserDao)Class.forName(daoClassName).newInstance();
}catch (Exception e) {
throw new RuntimeException(e);
}
}
private static final DaoFactory instance = new DaoFactory();
public static DaoFactory getInstance(){
return instance;
}
public UserDao createUserDao(){
return userdao;
}
}
- service
UserDao dao = DaoFactory.getInstance().createUserDao();
Внедрение зависимостей Spring
С помощью описанного выше процесса мы можем четко найти:Зависимости между объектами фактически присваивают значения свойствам объектов! Зависимости существуют, потому что у объектов есть переменные других объектов....
Spring предоставляет несколько способов присвоения значений свойствам
- 1) Через конструктор
- 2) Вводить значения в свойства через метод set
-
- p пространство имен
- 4) Автоматическая сборка (разбираюсь)
- 5) Аннотация
Настройка тестовой среды
-
Переменная userDao используется в UserService для поддержания зависимости от уровня Dao.
-
UserAction использует переменную userService для поддержания зависимостей со слоем службы.
-
userDao
public class UserDao {
public void save() {
System.out.println("DB:保存用户");
}
}
- userService
public class UserService {
private UserDao userDao;
public void save() {
userDao.save();
}
}
- userAnction
public class UserAction {
private UserService userService;
public String execute() {
userService.save();
return null;
}
}
Конструктор присваивает значение свойству
По сути, мы объясняемЯ уже говорил о создании конструктора с параметрами... подытожим..
насПросто проверьте зависимости между сервисом и дао....существуетДобавить конструктор в сервис, параметр userDao
public UserService(UserDao userDao) {
this.userDao = userDao;
//看看有没有拿到userDao
System.out.println(userDao);
}
Файл конфигурации applicationContext.xml
<!--创建userDao对象-->
<bean id="userDao" class="UserDao"/>
<!--创建userService对象-->
<bean id="userService" class="UserService">
<!--要想在userService层中能够引用到userDao,就必须先创建userDao对象-->
<constructor-arg index="0" name="userDao" type="UserDao" ref="userDao"></constructor-arg>
</bean>
- Тест: объект userDao может быть успешно получен
// 创建容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//得到service对象
UserService userService = (UserService) ac.getBean("userService");
Внедрение значений в свойства через set-методы
Здесь мы также тестируем зависимости между сервисом и уровнем dao...Внедрить userDao в UserService через метод set на сервисном уровне.
- Добавить метод set в UserService
public class UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
//看看有没有拿到userDao
System.out.println(userDao);
}
public void save() {
userDao.save();
}
}
Файл конфигурации applicationContext.xml: назначение свойств свойствам через узлы свойств
- Ссылочные типы используют атрибут ref
- Базовые типы используют атрибут value
<!--创建userDao对象-->
<bean id="userDao" class="UserDao"/>
<!--创建userService对象-->
<bean id="userService" class="UserService">
<property name="userDao" ref="userDao"/>
</bean>
- контрольная работа:
внутренняя фасоль
мы были простоСначала создайте объект userDao, а затем используйте userService для ссылки на объект userDao....у нас другой способ мышления:Сначала создайте userService, обнаружите, что userService нужны атрибуты userDao, а затем создайте userDao....посмотрим, как устроен такой образ мышления:
Файл конфигурации applicationContext.xml: узел свойств, встроенный узел компонента
<!--
1.创建userService,看到有userDao这个属性
2.而userDao这个属性又是一个对象
3.在property属性下又内置了一个bean
4.创建userDao
-->
<bean id="userService" class="UserService">
<property name="userDao">
<bean id="userDao" class="UserDao"/>
</property>
</bean>
- контрольная работа
Мы обнаружили, что этот способ мышления совпадает с порядком выполнения доступа к серверу, ноЕсли userDao будет использоваться другими службами несколько раз, его необходимо настроить несколько раз....
значение свойства внедрения пространства имен p
p имя управляет таким образомПо сути, это оптимизация заданного метода, который оптимизирует конфигурацию....p пространство имен этого содержимогоЕго необходимо использовать в версии Spring3 или выше....Давайте посмотрим:
Файл конфигурации applicationContext.xml: используйте пространство имен p
<bean id="userDao" class="UserDao"/>
<!--不用写property节点了,直接使用p名称空间-->
<bean id="userService" class="UserService" p:userDao-ref="userDao"/>
- контрольная работа
автоматическая сборка
Spring также предоставляет функцию автоматического подключения, что может значительно упростить нашу настройку.
По умолчанию автозагрузка не включена, обычно используются два типа автосборки:
- Собрать по имени
- Собрать по классу типа
Конфигурация XML по имени
Файл конфигурации applicationContext.xml: используйте автопроводку, согласно имени
<bean id="userDao" class="UserDao"/>
<!--
1.通过名字来自动装配
2.发现userService中有个叫userDao的属性
3.看看IOC容器中没有叫userDao的对象
4.如果有,就装配进去
-->
<bean id="userService" class="UserService" autowire="byName"/>
- контрольная работа
Конфигурация XML в соответствии с типом
Файл конфигурации applicationContext.xml: используйте автопроводку, в зависимости от типа
Стоит отметить, что:Если использовать автоматическую сборку по типам, в IOC-контейнере может быть только один такой тип, иначе будет выдано сообщение об ошибке!
<bean id="userDao" class="UserDao"/>
<!--
1.通过名字来自动装配
2.发现userService中有个叫userDao的属性
3.看看IOC容器UserDao类型的对象
4.如果有,就装配进去
-->
<bean id="userService" class="UserService" autowire="byType"/>
- контрольная работа:
Мы просто тестируем зависимости между двумя объектами, если у нас много объектов, мы также можемИспользовать автоматическое назначение по умолчанию
###Автопроводка с использованием аннотаций###
@Autowired аннотация для автопроводки:
- Можно декорировать на конструкторе
- Его также можно изменить в методе установки
- @Inject из java имеет ту же функциональность, что и @AutoWired.
Если нет подходящего bean-компонента, и во избежание исключений мы можем использовать для атрибута required значение false. 【Осторожность】
- тестовый код
@Component
public class UserService {
private UserDao userDao ;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
Успешно получить ссылку на userDao
Реализуйте зависимости объектов с помощью класса конфигурации JavaConfig.
Есть два способа (Но я не могу проверить это, если вы можете, дайте мне знать в комментариях.....)
- Первый тип (не тестировался)
import org.springframework.context.annotation.Bean;
@org.springframework.context.annotation.Configuration
public class Configuration {
@Bean()
public UserDao userDao() {
return new UserDao();
}
@Bean
public UserService userService() {
//直接调用@bean的方法
return new UserService(userDao());
}
}
- Второй (не могу проверить)
import org.springframework.context.annotation.Bean;
@org.springframework.context.annotation.Configuration
public class Configuration {
@Bean()
public UserDao userDao() {
return new UserDao();
}
@Bean
public UserService userService(UserDao userDao) {
//通过构造函数依赖注入
return new UserService(userDao);
}
}
- Если я прохожу напрямую через конструктор, то сообщается об ошибке
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.context.annotation.Bean;
@org.springframework.context.annotation.Configuration
public class Configuration {
@Bean()
public UserDao userDao() {
return new UserDao();
}
@Bean(autowire = Autowire.BY_TYPE)
public UserService userService(UserDao userDao) {
return new UserService(userDao);
}
}
- Только так я могу получить ссылку на userDao в своем тесте.
public class Configuration {
@Bean()
public UserDao userDao() {
return new UserDao();
}
@Bean(autowire = Autowire.BY_TYPE)
public UserService userService() {
return new UserService(userDao());
}
}
Конечно,Самый простой и понятный способЕсть еще один:Добавьте метод setUser() в UserService, а затем просто установите его в..
- UserService
public class UserService {
private UserDao userDao ;
public UserService() {
}
public UserService(UserDao userDao) {
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
- Config
import org.springframework.context.annotation.Bean;
@org.springframework.context.annotation.Configuration
public class Config1 {
@Bean(name = "userDao")
public UserDao userDao() {
return new UserDao();
}
@Bean(name="userService")
public UserService userService() {
UserService userService = new UserService();
userService.setUserDao(userDao());
return userService;
}
}
В конце концов
Расширенное чтение:
Если в статье есть какие-либо ошибки, пожалуйста, поправьте меня, и мы сможем общаться друг с другом. Учащиеся, привыкшие читать технические статьи в WeChat и желающие получить больше ресурсов по Java, могутОбратите внимание на публичный аккаунт WeChat: Java3y