Home

0

Spring Boot 게시판 만들기 19 - Build시 DB 연결 Bug Fix 및 Profile 설정

19. Build시 DB 연결 Bug Fix 및 Profile 설정Jenkins에서 build 오류Jenkins에서 Build를 진행하면 Test시 해당 오류가 발생하게 된다. Test를 진행하면서 DBConfigByYml 클래스내 필드를 Application-mysql.yml 를 이용해 채우게 되는데 Application-mysql.yml 파일이 Github에는 올라가 있지 않아 문제가 생기게 되는 것이다. > Task :testSampleBoardApplicationTests > contextLoads() FAILED java.lang.IllegalStateException at DefaultCacheAwareContextLoaderDelegate.java:132 Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException at ConstructorResolver.java:800 Caused by: org.springframework.beans.factory.BeanCreationException at AutowiredAnnotationBeanPostProcessor.java:405 Caused by: java.lang.IllegalArgumentException at PropertyPlaceholderHelper.java:1782021-02-24 16:17:02.458 INFO 1610 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'17 tests completed, 1 failed> Task :test FAILEDFAILURE: Build failed with an exception.* What went wrong:Execution failed for task ':test'.> There were failing tests. See the report at: file:///var/jenkins_home/workspace/sample-board/build/reports/tests/test/index.html* Try:Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.* Get more help at https://help.gradle.orgBUILD FAILED in 53s7 actionable tasks: 7 executedBuild step 'Invoke Gradle script' changed build result to FAILUREBuild step 'Invoke Gradle script' marked build as failureFinished: FAILURE 여러개의 @PropertySource 사용하기첫번째로 해결한 방법은 @PropertySource를 두개 사용하여 test를 진행할 시에는 H2 database를 바라보게 하고 운영시에는 MySQL을 바라 볼 수 있게 설정 파일을 두게 만들어 사용했다. @PropertySource는 순서에 따라 아래 값이 이전 값을 덮어 쓰게 된다. DBConfigByYml.java @Configuration@PropertySource(value = "classpath:application-h2.yml", factory = YamlPropertySourceFactory.class, ignoreResourceNotFound = true)@PropertySource(value = "classpath:application-mysql.yml", factory = YamlPropertySourceFactory.class, ignoreResourceNotFound = true)public class DBConfigByYml { @Value("${spring.datasource.driver-class-name}") private String driverClassName; @Value("${spring.datasource.url}") private String url; @Value("${spring.datasource.username}") private String username; @Value("${spring.datasource.password}") private String password; @Bean public DataSource dataSource() { return DataSourceBuilder.create() .driverClassName(driverClassName) .url(url) .username(username) .password(password) .build(); }} 여러개의 PropertySource 묶기

0

Spring Boot 게시판 만들기 18 - 외부로부터 설정 받기(yml)

18. 외부로부터 설정 받기(yml)YamlPropertySourceFactory.java public class YamlPropertySourceFactory implements PropertySourceFactory { @Override public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException { Properties propertiesFromYaml = loadYamlIntoProperties(resource); String sourceName = name != null ? name : resource.getResource().getFilename(); return new PropertiesPropertySource(sourceName, propertiesFromYaml); } private Properties loadYamlIntoProperties(EncodedResource resource) throws FileNotFoundException { try { YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean(); factory.setResources(resource.getResource()); factory.afterPropertiesSet(); return factory.getObject(); } catch (IllegalStateException e) { // for ignoreResourceNotFound Throwable cause = e.getCause(); if (cause instanceof FileNotFoundException) { throw (FileNotFoundException) e.getCause(); } throw e; } }} DBConfigByYml.java @Configuration@PropertySource(value = "classpath:application-mysql.yml", factory = YamlPropertySourceFactory.class)public class DBConfigByYml { @Value("${spring.datasource.driver-class-name}") private String driverClassName; @Value("${spring.datasource.url}") private String url; @Value("${spring.datasource.username}") private String username; @Value("${spring.datasource.password}") private String password; @Bean public DataSource dataSource(){ return DataSourceBuilder.create() .driverClassName(driverClassName) .url(url) .username(username) .password(password) .build(); }}

0

Spring Boot 게시판 만들기 17 - 외부로부터 설정 받기(property)

17. 외부로부터 설정 받기(property)Github에 프로젝트를 올릴때 데이터 베이스 접속 연결과 같은 민감한 정보는 다른 사람이 열람해서는 안되는 정보라 형상관리에서 제외한 상태로 올리게 된다. .gitignore **/application-mysql.yml**/application-mysql.properties 데이터베이스 접속을 위한 properties 만들기application-mysql.properties spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/{테이블}serverTimezone=UTC&characterEncoding=UTF-8spring.datasource.username={Username}spring.datasource.password={Password} TransactionManagementConfigurer은 Spring에서 데티어베이스 연결을 지원한다. DBConfig.java

0

스프링 핵심 원리 이해 - 객체 지향 원리 적용

목차 Post not found: spring-boot/spring-core/basic/basic2 객체 지향 설계 5원칙 SOLID DIP 원칙 위반 - 추상화와 구체화 둘다 의존MemberServiceImpl 클래스는 MemberRepository 인터페이스를 의존하면서 구현 클래스인 MemoryMemberRepository도 의존하고 있다. public class MemberServiceImpl implements MemberService{ // MemberServiceImpl 클래스는 MemberRepository 인터페이스와 구현체인 MemoryMemberRepository 둘다 의존하고 있다. private final MemberRepository memberRepository = new MemoryMemberRepository(); @Override public void join(Member member) { memberRepository.save(member); } @Override public Member findMember(Long memberId) { return memberRepository.findById(memberId); }} OrderServiceImpl 클래스는 MemberRepository 인터페이스와 DiscountPolicy 인터페이스를 의존하면서 구현 클래스인 MemoryMemberRepository 와 RateDiscountPolicy 를 의존하고 있다. 추상화와 구체화 둘다 의존하는 문제가 있다.–> DIP 위반 DIP의 원칙을 지키기 위해 의존 class내에서 구현 클래스를 가져오는 부분을 삭제하게 되면 객체가 존재하지 않아서 nullPointException이 발생한다. public class OrderServiceImpl implements OrderService { // OrderServiceImpl 클래스는 MemberRepository 인터페이스와 구현체인 MemoryMemberRepository // DiscountPolicy 인터페이스와 구현체인 RateDiscountPolicy 를 의존하는 문제점이 있다. private final MemberRepository memberRepository = new MemoryMemberRepository(); private final DiscountPolicy discountPolicy = new RateDiscountPolicy(); @Override public Order createOrder(Long memberId, String itemName, int itemPrice) { Member member = memberRepository.findById(memberId); int discountPrice = discountPolicy.discount(member, itemPrice); return new Order(memberId, itemName, itemPrice, discountPrice); }}

0

Spring Boot - 독립적으로 실행 가능한 JAR

독립적으로 실행 가능한 JAR앱을 어딘가에 배포하거나 도커 이미지로 만들거나 하기 위해서는 jar패키지로 패키징한 후 jar파일을 실행하는게 유용하다. jar파일 생성mvn package mvn pakcage명령어를 통해 앱을 jar파일로 생성한다. jar파일이 생성됨을 확인할 수 있다. jar파일 안에는 앱을 실행하기 위한 의존성(library)들이 전부 다 포함되어 있다. jar 파일 실행java -jar springinit-1.0-SNAPSHOT.jar

0

Spring Boot - 내장 웹 서버 응용 2부(HTTPS와 HTTP2)

내장 웹 서버 응용 2부 : HTTPS와 HTTP2https를 사용하기 위해서는 키스토어가 필요하다. 키스토어 생성# 저는 줄 바꿈 문자 해결 했습니당 ^^keytool -genkey \ -alias tomcat \ -storetype PKCS12 \ -keyalg RSA \ -keysize 2048 \ -keystore keystore.p12 \ -validity 4000 위 명령어를 사용하여 키 스토어를 생성할 수 있다. 키 저장소 비밀번호 입력:새 비밀번호 다시 입력:이름과 성을 입력하십시오. [Unknown]: dongwoo yang조직 단위 이름을 입력하십시오. [Unknown]: island조직 이름을 입력하십시오. [Unknown]: ceo구/군/시 이름을 입력하십시오? [Unknown]: seongbuk시/도 이름을 입력하십시오. [Unknown]: seoul이 조직의 두 자리 국가 코드를 입력하십시오. [Unknown]: krCN=dongwoo yang, OU=island, O=ceo, L=seongbuk, ST=seoul, C=kr이(가) 맞습니까? [아니오]: 예 해당 질문들이 나오는데, 마지막에 “네” 혹은 “yes”를 하게 되면 무한루프에 빠지게 된다….. 예라고 꼭!!!! 적어주도록…. key를 생성하게 된 다음에 git을 사용하고 있는 중이라면 꼭!!! gitignore에 추가하자!!! 키스토어 사용을 위한 세팅해주기

0

Spring Boot - 내장 웹 서버 응용 1부(컨테이너와 포트)

내장 웹 서버 응용 1부 : 컨테이너와 포트https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-web-servers.html에 다른 서블릿 컨테이너를 사용하는 방법이 적혀져 있다. tomcat 빼기 일단, spring-boot-starter-web에 적재되어 있는 tomcat을 뺄 필요가 있다. <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions></dependency> 톰켓을 뺀 후 아무것도 추가하지 않으면 웹 어플리케이션으로 작동하지 않고 어플리케이션으로 작동하기 때문에 그냥 종료된다. 다른 컨테이너 추가하기Jetty

0

Spring Boot - 내장 웹 서버 이해

내장 웹 서버 이해내장 서버를 스프링 부트 없이 만들어 보기 springbootgetttingstarted public class Application { public static void main(String[] args) throws LifecycleException { // 톰캣 만들기 Tomcat tomcat = new Tomcat(); tomcat.setPort(8888); Context context = tomcat.addContext("/", "/"); // servlet 만들기 HttpServlet servlet = new HttpServlet(){ @Override // get요청에 관한 메소드 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // response 객체의 writer객체를 반환받아 // 응답으로 전해줄 servlet을 작성해준다. PrintWriter writer = resp.getWriter(); writer.println("<html><head><title>"); writer.println("Hey, Tomcat"); writer.println("</title></head>"); writer.println("<body><h1>Hello Tomcat</h1></body>"); writer.println("</html>"); } }; String servletName = "helloServlet"; // 톰켓에 서블릿을 추가해준 후 tomcat.addServlet("/", servletName, servlet); // /hello url과 해당 서블릿을 매핑 시켜준다. context.addServletMappingDecoded("/hello", servletName); tomcat.getConnector(); tomcat.start(); tomcat.getServer().await(); }} tomcat9부터는 tomcat.start()를 하기 전에 tomcat.getConnector()를 해야 실행이 된다. tomcat 객체를 생성 servlet 객체를 생성했다. 결과 스프링 부트에서는 위와 같은 설정을 AutoConfiguration에서 자동으로 잡아준다.

0

Spring Boot - 자동 설정 만들기 1부

자동 설정 만들기 2부EnableAutoConfiguration이 불러오는 같은 Bean 무시하기 maplespringbootstarter 프로젝트 @Configurationpublic class HolomanConfiguration { @Bean @ConditionalOnMissingBean public Holoman holoman(){ Holoman holoman = new Holoman(); holoman.setHowLong(5); holoman.setName("maple"); return holoman; }} @ConditionalOnMissingBean을 사용하면 해당 Bean이 없는 경우에만 EnableAutoConfiguration을 통해 Bean이 추가 된다. 결과2020-03-15 21:31:49.936 INFO 67228 --- [ main] com.example.Application : Starting Application on yangdong-uui-MacBookPro.local with PID 67228 (/Users/dongwoo-yang/dev/study/spring/everyday_spring/chapter3/ch3_5/springbootgettingstarted/target/classes started by dongwoo-yang in /Users/dongwoo-yang/dev/study/spring/everyday_spring/chapter3/ch3_5/springbootgettingstarted)2020-03-15 21:31:49.938 INFO 67228 --- [ main] com.example.Application : No active profile set, falling back to default profiles: default2020-03-15 21:31:50.581 INFO 67228 --- [ main] com.example.Application : Started Application in 0.937 seconds (JVM running for 1.598)Holoman{name='동장군', howLong=60}Process finished with exit code 0 springbootgetttingstarted프로젝트의 Bean이 출력됨을 확인할 수 있다. application.properties를 이용한 방법