플라이웨이 Java 기반 마이그레이션에는 스프링 콩이 주입되지 않습니다.
플라이웨이 마이그레이션 Java 코드에 구성 속성 구성 요소를 삽입하려고 하지만 항상 null입니다.
저는 플라이웨이에서 스프링 부츠를 사용하고 있습니다.
@Component
@ConfigurationProperties(prefix = "code")
public class CodesProp {
private String codePath;
}
그런 다음 Flyway 마이그레이션 코드에서 이 구성 요소를 다음과 같이 자동 작성하려고 시도합니다.
public class V1_4__Migrate_codes_metadata implements SpringJdbcMigration {
@Autowired
private CodesProp codesProp ;
public void migrate(JdbcTemplate jdbcTemplate) throws Exception {
codesProp.getCodePath();
}
여기서 codesProp은 항상 null입니다.
플라이웨이 안에 스프링 원두를 주입하거나 플라이웨이 원두보다 먼저 초기화할 수 있는 방법이 있습니까?
감사해요.
Flyway는 종속성 주입을 지원하지 않습니다.SpringJdbcMigration
실행.단순히 클래스 경로에서 다음을 구현하는 클래스를 찾습니다.SpringJdbcMigration
기본 생성자를 사용하여 새 인스턴스를 만듭니다.이 작업은 SpringJdbcMigrationResolver에서 수행됩니다.마이그레이션이 실행되면 SpringJdbcMigration실행자가 새 항목을 만듭니다.JdbcTemplate
마이그레이션 구현을 호출합니다.migrate
방법.
Java 기반 마이그레이션에 종속성을 주입해야 하는 경우 자체적으로 마이그레이션을 구현해야 합니다.MigrationResolver
응용프로그램 컨텍스트에서 특정 유형의 콩을 검색하고 생성하고 반환하는 것.ResolvedMigration
각각의 인스턴스.
저처럼 Flyway 4.1을 기다리지 않으려면 Flyway 4.0을 사용하고 다음을 Spring Boot 응용 프로그램에 추가할 수 있습니다.
작성ApplicationContextAwareSpringJdbcMigrationResolver
프로젝트의 클래스:
import org.flywaydb.core.api.FlywayException;
import org.flywaydb.core.api.MigrationType;
import org.flywaydb.core.api.MigrationVersion;
import org.flywaydb.core.api.configuration.FlywayConfiguration;
import org.flywaydb.core.api.migration.MigrationChecksumProvider;
import org.flywaydb.core.api.migration.MigrationInfoProvider;
import org.flywaydb.core.api.migration.spring.SpringJdbcMigration;
import org.flywaydb.core.api.resolver.ResolvedMigration;
import org.flywaydb.core.internal.resolver.MigrationInfoHelper;
import org.flywaydb.core.internal.resolver.ResolvedMigrationComparator;
import org.flywaydb.core.internal.resolver.ResolvedMigrationImpl;
import org.flywaydb.core.internal.resolver.spring.SpringJdbcMigrationExecutor;
import org.flywaydb.core.internal.resolver.spring.SpringJdbcMigrationResolver;
import org.flywaydb.core.internal.util.ClassUtils;
import org.flywaydb.core.internal.util.Location;
import org.flywaydb.core.internal.util.Pair;
import org.flywaydb.core.internal.util.StringUtils;
import org.flywaydb.core.internal.util.scanner.Scanner;
import org.springframework.context.ApplicationContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
/**
* Migration resolver for {@link SpringJdbcMigration}s which are registered in the given {@link ApplicationContext}.
* This resolver provides the ability to use other beans registered in the {@link ApplicationContext} and reference
* them via Spring's dependency injection facility inside the {@link SpringJdbcMigration}s.
*/
public class ApplicationContextAwareSpringJdbcMigrationResolver extends SpringJdbcMigrationResolver {
private final ApplicationContext applicationContext;
public ApplicationContextAwareSpringJdbcMigrationResolver(Scanner scanner, Location location, FlywayConfiguration configuration, ApplicationContext applicationContext) {
super(scanner, location, configuration);
this.applicationContext = applicationContext;
}
@SuppressWarnings("unchecked")
@Override
public Collection<ResolvedMigration> resolveMigrations() {
// get all beans of type SpringJdbcMigration from the application context
Map<String, SpringJdbcMigration> springJdbcMigrationBeans =
(Map<String, SpringJdbcMigration>) this.applicationContext.getBeansOfType(SpringJdbcMigration.class);
ArrayList<ResolvedMigration> resolvedMigrations = new ArrayList<ResolvedMigration>();
// resolve the migration and populate it with the migration info
for (SpringJdbcMigration springJdbcMigrationBean : springJdbcMigrationBeans.values()) {
ResolvedMigrationImpl resolvedMigration = extractMigrationInfo(springJdbcMigrationBean);
resolvedMigration.setPhysicalLocation(ClassUtils.getLocationOnDisk(springJdbcMigrationBean.getClass()));
resolvedMigration.setExecutor(new SpringJdbcMigrationExecutor(springJdbcMigrationBean));
resolvedMigrations.add(resolvedMigration);
}
Collections.sort(resolvedMigrations, new ResolvedMigrationComparator());
return resolvedMigrations;
}
ResolvedMigrationImpl extractMigrationInfo(SpringJdbcMigration springJdbcMigration) {
Integer checksum = null;
if (springJdbcMigration instanceof MigrationChecksumProvider) {
MigrationChecksumProvider version = (MigrationChecksumProvider) springJdbcMigration;
checksum = version.getChecksum();
}
String description;
MigrationVersion version1;
if (springJdbcMigration instanceof MigrationInfoProvider) {
MigrationInfoProvider resolvedMigration = (MigrationInfoProvider) springJdbcMigration;
version1 = resolvedMigration.getVersion();
description = resolvedMigration.getDescription();
if (!StringUtils.hasText(description)) {
throw new FlywayException("Missing description for migration " + version1);
}
} else {
String resolvedMigration1 = ClassUtils.getShortName(springJdbcMigration.getClass());
if (!resolvedMigration1.startsWith("V") && !resolvedMigration1.startsWith("R")) {
throw new FlywayException("Invalid Jdbc migration class name: " + springJdbcMigration.getClass()
.getName() + " => ensure it starts with V or R," + " or implement org.flywaydb.core.api.migration.MigrationInfoProvider for non-default naming");
}
String prefix = resolvedMigration1.substring(0, 1);
Pair info = MigrationInfoHelper.extractVersionAndDescription(resolvedMigration1, prefix, "__", "");
version1 = (MigrationVersion) info.getLeft();
description = (String) info.getRight();
}
ResolvedMigrationImpl resolvedMigration2 = new ResolvedMigrationImpl();
resolvedMigration2.setVersion(version1);
resolvedMigration2.setDescription(description);
resolvedMigration2.setScript(springJdbcMigration.getClass().getName());
resolvedMigration2.setChecksum(checksum);
resolvedMigration2.setType(MigrationType.SPRING_JDBC);
return resolvedMigration2;
}
}
Spring Boot 생성 Flyway 인스턴스를 후처리할 새 구성 클래스를 추가합니다.
import org.flywaydb.core.Flyway;
import org.flywaydb.core.internal.dbsupport.DbSupport;
import org.flywaydb.core.internal.dbsupport.h2.H2DbSupport;
import org.flywaydb.core.internal.dbsupport.mysql.MySQLDbSupport;
import com.pegusapps.zebra.infrastructure.repository.flyway.ApplicationContextAwareSpringJdbcMigrationResolver;
import org.flywaydb.core.internal.resolver.sql.SqlMigrationResolver;
import org.flywaydb.core.internal.util.Location;
import org.flywaydb.core.internal.util.PlaceholderReplacer;
import org.flywaydb.core.internal.util.scanner.Scanner;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;
@Configuration
@ComponentScan("db.migration")
public class FlywayConfiguration {
@Bean
public BeanPostProcessor postProcessFlyway(ApplicationContext context) {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
return o;
}
@Override
public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
if (o instanceof Flyway) {
Flyway flyway = (Flyway) o;
flyway.setSkipDefaultResolvers(true);
ApplicationContextAwareSpringJdbcMigrationResolver resolver = new ApplicationContextAwareSpringJdbcMigrationResolver(
new Scanner(Thread.currentThread().getContextClassLoader()),
new Location("classpath:db/migration"),
context.getBean(org.flywaydb.core.api.configuration.FlywayConfiguration.class),
context);
SqlMigrationResolver sqlMigrationResolver = null;
try {
sqlMigrationResolver = new SqlMigrationResolver(
getDbSupport(),
new Scanner(Thread.currentThread().getContextClassLoader()),
new Location("classpath:db/migration"),
PlaceholderReplacer.NO_PLACEHOLDERS,
"UTF-8",
"V",
"R",
"__",
".sql");
} catch (SQLException e) {
e.printStackTrace();
}
flyway.setResolvers(sqlMigrationResolver, resolver);
}
return o;
}
private DbSupport getDbSupport() throws SQLException {
DataSource dataSource = context.getBean(DataSource.class);
if( ((org.apache.tomcat.jdbc.pool.DataSource)dataSource).getDriverClassName().equals("org.h2.Driver"))
{
return new H2DbSupport(dataSource.getConnection());
}
else
{
return new MySQLDbSupport(dataSource.getConnection());
}
}
};
}
}
나는 tomcat jdbc 풀, h2 및 mysql에 대해 하드코드된 종속성을 가지고 있습니다.만약 당신이 다른 것을 사용하고 있다면, 당신은 그곳에서 코드를 변경해야 할 것입니다 (만약 그것을 피하는 방법을 아는 사람이 있다면, 댓글을 달아주세요!)
또한 참고:@ComponentScan
패키지는 Java 마이그레이션 클래스를 배치할 위치와 일치해야 합니다.
또한 추가해야 했습니다.SqlMigrationResolver
마이그레이션의 SQL 및 Java 버전을 모두 지원하고 싶기 때문에 다시 시작합니다.
에서 Java 클래스를 만듭니다.db.migrations
실제 마이그레이션을 수행하는 패키지:
@Component
public class V2__add_default_surveys implements SpringJdbcMigration {
private final SurveyRepository surveyRepository;
@Autowired
public V2__add_surveys(SurveyRepository surveyRepository) {
this.surveyRepository = surveyRepository;
}
@Override
public void migrate(JdbcTemplate jdbcTemplate) throws Exception {
surveyRepository.save(...);
}
}
클래스를 a로 만들어야 합니다.@Component
그리고 그것은 그것을 구현할 필요가 있습니다.SpringJdbcMigration
이 클래스에서는 마이그레이션에 필요한 컨텍스트의 Springbean에 Spring 생성자 주입을 사용할 수 있습니다.
참고: Flyway가 실행되기 전에 유효성 검사가 실행되는 것 같기 때문에 Hibernate의 ddl 유효성 검사를 사용하지 않도록 설정해야 합니다.
spring.jpa.hibernate.ddl-auto=none
간단히 말해서, db 마이그레이션에서 빈을 자동 배선하거나 응용프로그램에서 참조 클래스를 자동 배선하지 마십시오!마이그레이션에서 참조한 클래스를 리팩터/삭제/변경하면 마이그레이션이 컴파일되지 않거나 더 심하게 손상될 수 있습니다.
마이그레이션에 일반 JDBC 템플릿을 사용하는 오버헤드는 위험을 감수할 가치가 없습니다.
델타 스파이크를 사용하는 경우 BeanProvider를 사용하여 클래스에 대한 참조를 얻을 수 있습니다.여기 DAO의 예가 있지만, 여러분의 수업에서도 잘 작동할 것입니다.
DAO 코드 변경:
public static UserDao getInstance() {
return BeanProvider.getContextualReference(UserDao.class, false, new DaoLiteral());
}
그런 다음 마이그레이션 방법:
UserDao userdao = UserDao.getInstance();
그리고 여기에 당신의 참조가 있습니다.
(참조:Java를 사용한 플라이웨이 마이그레이션)
언급URL : https://stackoverflow.com/questions/34923868/spring-beans-are-not-injected-in-flyway-java-based-migration
'bestsource' 카테고리의 다른 글
PHP 출력을 변수로 캡처하려면 어떻게 해야 합니까? (0) | 2023.07.23 |
---|---|
연결 시 Java 애플리케이션이 Oracle에 대해 식별되도록 하려면 어떻게 해야 합니까? (0) | 2023.07.23 |
테이블에 열이 너무 많으면 성능이 저하됩니까? (0) | 2023.07.23 |
MySQL 쿼리가 임의로 지연됨 (0) | 2023.07.23 |
PHP 실제 최대 업로드 크기 가져오기 (0) | 2023.07.23 |