Миграция с SpringMVC на Springboot

задняя часть Spring MyBatis MVC

В процессе переноса проекта SpringMVC на Springboot в основном были сделаны следующие вещи

  • Конфигурация профиля
  • Глобальные переменные считываются из файла свойств
  • Источник данных и конфигурация Mybatis
  • конфигурация файла журнала
  • Конфигурация WebConfig (включая исходный файл web.xml и spring-mvc.xml)
  • Удалить избыточную инъекцию bean-компонента

Помимо ознакомления с тем, что сделано и как это сделать, в этой статье будет много лишней чепухи.По поводу некоторых рассуждений о принципе, вы должны знать, почему это так.

Конфигурация профиля

В традиционном проекте Spring метод настройки нескольких профилей заключается в записи нескольких профилей в файл pom.xml, а затем предварительной загрузке выбранной среды профиля путем выполнения файла maven перед запуском проекта. После загрузки, когда проект выполняется, он решает, какой файл .properties загрузить в глобальную переменную в соответствии с загруженной средой.

Управление несколькими профилями в Springboot очень простое.

Профиль можно выбрать, когда пакет jar запускается из командной строки.

java -jar example.jar --spring.profiles.active=test

Или настройте его в глобальной конфигурации application.properties

在application.properties中添加spring.profiles.active=test

Вышеуказанные два метода могут запускать «тестовый» профиль, первый имеет более высокий приоритет при выполнении, чем второй.

(Кстати, в Springboot эти два метода по существу используют метод «внешней конфигурации» для редактирования и замены среды)

Кроме того,Каждый отдельный профиль настраивается в формате «application-xxx.properties»., для каждой отдельной среды, например:

  • application-pro.properties представляет промежуточную среду
  • application-dev.properties представляет среду разработки
  • application-test.properties представляет тестовую среду

Когда нам нужно проверить, нормально ли загружается профиль, мы можем прописать это в соответствующем файле .properties

server.port=9080

При запуске видно, запущен ли порт.

Здесь вы можете указать порядок, в котором Springboot загружает файлы конфигурации.

  • Свойства глобальных настроек devtools в домашнем каталоге ( ~/.spring-boot-devtools.properties , если devtools активирован).
  • Аннотация @TestPropertySource к тестовым примерам.
  • Аннотация @SpringBootTest#properties к тестовому примеру.
  • аргументы командной строки
  • Свойства из SPRING_APPLICATION_JSON (переменные среды или встроенный JSON, встроенный в системные свойства).
  • Параметры инициализации ServletConfig.
  • Параметры инициализации ServletContext.
  • Свойства JNDI из java:comp/env.
  • Системные свойства Java (System.getProperties()).
  • Переменные среды операционной системы.
  • RandomValuePropertySource, содержащий только свойства в случайном порядке.*.
  • Свойства приложения для конкретного профиля ( application-{profile}.properties и переменные YAML), которые не вводятся в банку.
  • Свойства приложения для конкретного профиля ( application-{profile}.properties и переменные YAML), введенные в банку.
  • Конфигурация приложения (application.properties и переменные YAML), которая не введена в банку.
  • Конфигурация приложения (переменные application.properties и YAML), введенная в банку.
  • Аннотация @PropertySource к классам @Configuration.
  • Свойства по умолчанию (указаны с помощью SpringApplication.setDefaultProperties).

Глобальные переменные считываются из файла свойств

В предыдущем разделе я написал настройку свойств для разных окружений, здесь я напишу о том, как записать эти свойства в глобальные переменные, чтобы потом их можно было вызывать напрямую в других местах.

/**
 * 全局变量
 */
public class Global {

	public static String examplePath;

	@Value("${example_path}")
    public void setExamplePath(String example) {
        Global.examplePath = examplePath;
    }
}

Таким образом, мы поместим файл .properties в

example_path=http://localhost:9090

Это свойство считывается в глобальную переменную.

Источник данных и конфигурация Mybatis

В традиционном проекте Spring используйте Mybatis для подключения к базе данных.

  • Сначала создайте bean-компонент с именем datasource
  • Затем соберите этот источник данных в SqlSessionFactory.
  • Наконец, соберите SqlSessionFactory в MapperScannerConfigurer.

Все это настраивается в файле конфигурации xml, что довольно громоздко.В Springboot такой XML-конфигурации следует избегать, насколько это возможно.

Mybatis теперь поддерживает Springboot, нам просто нужно добавитьMyBatis-Spring-Boot-StarterЭта зависимость сделает для нас следующие вещи:

  • Автоматически определять существующий источник данных
  • Создайте экземпляр SqlSessionFactory для SqlSessionFactoryBean и соберите в него источник данных.
  • Создайте экземпляр SqlSessionTemplate и соберите в него SqlSessionFactory.
  • Автоматически сканируйте ваши преобразователи, подключайте их к SqlSessionTemplate и регистрируйте их в контексте Spring, чтобы их можно было внедрить в другие компоненты.

Итак, в конфигурации Springboot Mybatis нам нужно сделать следующее:

  1. Заполните информацию о базе данных в application-{profile}.properties, например:
spring.datasource.url=jdbc:oracle:thin:@//localhost:1234/example
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.maxActive=10
spring.datasource.maxIdle=5
spring.datasource.maxWait=-1

Таким образом, мы зарегистрировали компонент источника данных в контексте Spring.

  1. Создайте файл MybatisConfig и замените xml на java:
/**
 * Created by WuTaoyu on 2017/12/7.
 */
@Configuration
@EnableTransactionManagement
@MapperScan("com.example.db.dao")
public class MybatisConfig {

    @Autowired
    private DataSource dataSource;

    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactoryBean() {
        SqlSessionFactoryBean sqlsession = new SqlSessionFactoryBean();
        sqlsession.setDataSource(dataSource);
        try {
            //添加XML目录
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            sqlsession.setMapperLocations(resolver.getResources("classpath:mapping/*.xml"));
            return sqlsession.getObject();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Bean
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return new DataSourceTransactionManager(dataSource);
    }


    @Bean(name = "exampleSequence")
    public OracleSequenceMaxValueIncrementer exampleSequenceBean(){
        OracleSequenceMaxValueIncrementer exampleSequence = new OracleSequenceMaxValueIncrementer();
        exampleSequence.setIncrementerName("EXAMPLE_SEQ");
        exampleSequence.setDataSource(dataSource);
        return exampleSequence;
    }
}

@MapperScan предназначен для сканирования картографа в этом пакете.

Кроме того, расположение mapper.xml здесь заключается в создании папки сопоставления в папке ресурсов и размещении ее ниже.

Здесь функция похожа на XML, она описывает традиционное xml-выражение с файлами .java и, по сути, шаг за шагом внедряет источник данных.

Поскольку в примере используется база данных Oracle, последний примерSequence должен продемонстрировать, как добавить последовательность.

  1. Аннотировать интерфейс всех картографов @Mapper

Например:

@Mapper
public interface UserMapper {
	...
}

конфигурация файла журнала

Logback поддерживает внешнюю конфигурацию в виде свойств, но для более детальной настройки по-прежнему используется конфигурация xml.

Чтобы XML-файл мог считывать некоторые пути из файла .properties, например, статическую конфигурацию, которую может потребоваться часто изменять, ее необходимо настроить в logback-spring.xml.

	<property resource="application.properties" />
    <property name="log.root.level" value="${log.root.level}" />
    <property name="log.path" value="${log.path}" />
    <property name="log.moduleName" value="${log.module}" />

Таким образом, файл application.properties можно

log.path=/home/logs/example
log.root.level=INFO
log.module=example

Прочитайте его в logback-spring.xml, а затем вызовите его.

Конфигурация WebConfig

Основная функция WebConfig — заменить web.xml и spring-mvc.xml для некоторой базовой конфигурации.

  1. О файле web.xml

Традиционные проекты Spring имеют настроенный файл web.xml.Функция этого файла такова: когда мы помещаем военный пакет в контейнер приложения (например, tomcat) для запуска, контейнер загружает фильтр (фильтр) в соответствии с web.xml , Конфигурации, такие как сервлет, страница ошибок, список приветственных файлов, прослушиватель (слушатель), параметр контекста (параметр контекста), ресурс-ссылка (конфигурация ресурса).

Здесь загружается прослушиватель, включая ContextLoaderListener, чтобы автоматически собирать информацию о конфигурации ApplicationContext при запуске контейнера.

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Этот ApplicationContext является ядром Spring IOC (унаследованным от BeanFactory), и в это время будут созданы экземпляры всех одноэлементных компонентов.

И здесь также загружается очень важный DispatcherServlet в SpringMVC, и какой файл xml используется для настройки DispatcherServlet.

<servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <!--<async-supported>true</async-supported>-->
</servlet>
  1. О spring-mvc.xml

spring-mvc.xml — это файл конфигурации SpringMVC, в котором мы можем настроить bean-компоненты, которые мы представили и которые необходимо настроить, такие как ViewResolver, multipartResolver, конвертер сообщений HTTP, пользовательский перехватчик и так далее.

Вышесказанное не имеет никакого отношения к Springboot, в основном для того, чтобы знать, что это такое и зачем, если вам не интересно, то можете пропустить.

Вернемся к настройке Springboot. В Springboot есть поговорка, что «соглашение лучше, чем конфигурация», что означает попытку использовать согласованный метод вместо его конкретной настройки (настройте его, когда требуется специальная конфигурация).

вводитьspring-boot-starter-webПосле этой зависимости "из коробки"spring-boot-starter-webсодержитspring-boot-autoconfigure.

С этой зависимостью вы можете использовать аннотацию @EnableAutoCongiguration. Эта аннотация угадает нужную вам конфигурацию Spring на основе импортированных зависимостей и настроит ее для вас. потому что он был введенspring-boot-starter-webЕсли это так, эта аннотация настроит веб-конфигурацию.

Кроме того, аннотация @SpringBootApplication уже содержит аннотацию @EnableAutoCongiguration. Поэтому, если вы аннотируете @SpringBootApplication в классе запуска ExampleServerApplication, веб-конфигурация может быть настроена автоматически.

Конечно, у нас все еще могут быть некоторые специальные конфигурации, в настоящее время мы можем создать WebConfig для настройки

/**
 * Created by WuTaoyu on 2017/12/8.
 */
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(marshallingHttpMessageConverter());
    }

    public MarshallingHttpMessageConverter marshallingHttpMessageConverter(){
        MarshallingHttpMessageConverter marshallingHttpMessageConverter = new MarshallingHttpMessageConverter();
        List<MediaType> mediaTypes = new ArrayList<MediaType>();
        mediaTypes.add(MediaType.TEXT_XML);
        mediaTypes.add(MediaType.APPLICATION_XML);
        XStreamMarshaller xStreamMarshaller=new XStreamMarshaller();
        marshallingHttpMessageConverter.setSupportedMediaTypes(mediaTypes);
        marshallingHttpMessageConverter.setMarshaller(xStreamMarshaller);
        marshallingHttpMessageConverter.setUnmarshaller(xStreamMarshaller);
        return marshallingHttpMessageConverter;
    }
    //配置文件上传
    @Bean(name = {"multipartResolver"})
    public MultipartResolver multipartResolver(){
        CommonsMultipartResolver commonsMultipartResolver=new CommonsMultipartResolver();
        commonsMultipartResolver.setDefaultEncoding("utf-8");
        commonsMultipartResolver.setMaxUploadSize(10485760000L);
        commonsMultipartResolver.setMaxInMemorySize(40960);
        return commonsMultipartResolver;
    }
    //异常处理
    @Bean
    public ExceptionHandler exceptionResolver(){
        ExceptionHandler exceptionHandler = new ExceptionHandler();
        return exceptionHandler;
    }
    //拦截器
    @Override
    public void addInterceptors(InterceptorRegistry registry){
        registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
}

Этот пример файла, который я написал, делает несколько вещей:

  • Представляем конвертер сообщений XML Http
  • Ввести multipartResolver
  • Ввести пользовательский обработчик исключений
  • Внедрить пользовательский перехватчик

Удалить избыточную инъекцию bean-компонента

Это не по теме, но одна из проблем, с которыми я действительно столкнулся.

При фактическом запуске проекта Springboot я обнаружил некоторые проблемы, о которых не сообщается в традиционных проектах Spring, то есть избыточное внедрение bean-компонентов.

В традиционном проекте Spring это не ошибка, но в проекте Springboot сообщается об ошибке. Я предполагаю, что это связано с тем, что когда имя метода класса bean-компонента для внедрения относительно упрощено, оно будет повторяться с некоторыми bean-компонентами, автоматически настроенными самим Springboot, и будет сообщено об ошибке.

Итак, избавьтесь от некоторых бобов, которые не нужно вводить.