SpringBoot 의 devtools 사용 으로 인 한 유형 변환 이상 문 제 를 해결 합 니 다.

질문:
최근 새 프레임 워 크 SpringBoot+shiro+spring-data-jpa 를 사용 할 때 spring 자체 의 열 배치 도 구 를 편리 하 게 체험 하기 위해 도입 했다.

<dependency> 

   <groupId>org.springframework.boot</groupId> 
   <artifactId>spring-boot-devtools</artifactId> 
   <!-- optional=true,      ,     devtools;    myboot           devtools,       --> 

   <optional>true</optional>
 </dependency>
처음에는 별 문제 가 없 었 습 니 다.shiro 의 session 관 리 를 사 용 했 고 session Dao 는 redis 로 이 루어 졌 습 니 다.그리고 Session 액세스 속성 을 사 용 했 을 때 저 장 된 속성 을 발견 하고 꺼 내 면 유형 전환 이상 이 발생 합 니 다.ClassCastException
분석:
그리고 자신 이 큰 푸 시 유닛 테스트 시 뮬 레이 션 을 썼 는데 문제 가 없 었 습 니 다.나중에 갑자기 ClassLoader 가 다 르 기 때문에 유형 전환 이 이상 한 것 이 아니 냐 는 것 을 깨 달 았 습 니 다.그리고 다음 프로젝트 가 시 작 될 때 항목 을 불 러 올 때 사용 하 는 클래스 가 모두
org.springframework.boot.devtools.restart.classloader.RestartClassLoader
shiro session 에서 꺼 낸 대상(redis 에서 반 직렬 화 된)의 클래스 로 더 는 모두
sun.misc.Launcher.AppClassLoader
형식 변환 이상 을 초래 할 수 있 음 이 분명 합 니 다.원래 Spring 의 dev-tools 는 class 를 다시 불 러 오기 위해 클래스 로 더 를 실 현 했 습 니 다.프로젝트 에서 바 뀔 클래스 를 불 러 오고 재 부팅 할 때 새로 바 뀐 내용 을 업데이트 할 수 있 습 니 다.사실은 그 중에서 공식 문서 에 명 시 된 바 가 있 습 니 다.
By default, any open project in your IDE will be loaded using the “restart” classloader, and any regular .jar file will be loaded using the “base” classloader. If you work on a multi-module project, and not each module is imported into your IDE, you may need to customize things. To do this you can create a META-INF/spring-devtools.properties file. The spring-devtools.properties file can contain restart.exclude. and restart.include. prefixed properties. The include elements are items that should be pulled up into the “restart” classloader, and the exclude elements are items that should be pushed down into the “base” classloader. The value of the property is a regex pattern that will be applied to the classpath.
해결:
프로젝트 1.솔 루 션 은 resources 디 렉 터 리 아래 에 META-INF 폴 더 를 만 든 다음 에 spring-devtools.properties 파일 을 만 드 는 것 입 니 다.파일 에 다음 과 같은 설정 을 추가 합 니 다.
restart.exclude.companycommonlibs=/mycorp-common-[\w-]+.jar restart.include.projectcommon=/mycorp-myproj-[\w-]+.jar
All property keys must be unique. As long as a property starts with restart.include. or restart.exclude. it will be considered. All META-INF/spring-devtools.properties from the classpath will be loaded. You can package files inside your project, or in the libraries that the project consumes.
프로젝트 2.spring-boot-devtools 를 사용 하지 않 습 니 다.
방안 에 대해 상세 한 사례 를 만들어 분석 하고 설명 하 며 문 제 를 해결 하 다.
우선 jar 가방 을 준비 하 세 요.그 안에 직렬 화 및 반 직렬 화 기능 이 포함 되 어 있 습 니 다.
springboot 프로젝트 에 패키지 도입

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-devtools</artifactId>
</dependency>
<!--                        -->
<dependency>
  <groupId>com.example</groupId>
  <artifactId>devtools-serialization</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>
springboot 프로젝트 를 간단하게 설정 하고 jar 의 직렬 화 도구 류 를 사용 하여 처리 대상 을 다음 과 같이 모 의 합 니 다.

@SpringBootApplication
public class PortalApplication {
  public static void main(String[] args) throws Exception {
    ConfigurableApplicationContext context = SpringApplication.run(PortalApplication.class, args);
    DemoBean demoBean = new DemoBean();
    SerializationUtils.serialize(demoBean);
    Object deserialize = SerializationUtils.deserialize();
    System.out.println(PortalApplication.class.getClassLoader());
    //       Object  
    System.out.println(deserialize);
    System.out.println(deserialize.getClass().getClassLoader());
    context.getBeanFactory().destroySingletons();
  }
}
위 와 같이 오 류 를 보고 하지 않 습 니 다.Object 는 boottstrap 유도 류 로 더 를 불 러 오기 때문에 문제 가 되 지 않 습 니 다.
근 데 이렇게 바 뀌 면

//...
 public static void main(String[] args) throws Exception {
    ConfigurableApplicationContext context = SpringApplication.run(PortalApplication.class, args);
    DemoBean demoBean = new DemoBean();
    SerializationUtils.serialize(demoBean);
    Object deserialize = SerializationUtils.deserialize();
    System.out.println(PortalApplication.class.getClassLoader());
    //             
    System.out.println((DemoBean)deserialize);
    System.out.println(deserialize.getClass().getClassLoader());
    context.getBeanFactory().destroySingletons();
  }
  //...
결 과 는 던 질 것 이다.
Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) Caused by: java.lang.ClassCastException: com.sample.serial.DemoBean cannot be cast to com.sample.serial.DemoBean at com.sample.PortalApplication.main(PortalApplication.java:27) ... 5 more
위 에서 출력 한 ClassLoader 정 보 를 살 펴 보면 각각
org.springframework.boot.devtools.restart.classloader.RestartClassLoader@63059d5a sun.misc.Launcher$AppClassLoader@18b4aac2
문제 가 없 는데 도 ClassCastException 의 근원 을 던 진 이유 다.
그렇다면 이 문 제 를 어떻게 해결 할 것 인가?
출력 된 ClassLoader 정 보 를 일치 시 키 면 됩 니 다.
AppClassLoader
스프링 공식 문서 에서 제시 한 설정 방법 을 참고 하여 처리 합 니 다.
resources 에서 META-INF/spring-devtools.properties 만 들 기
그림:

다음 단 계 는 spring-devtools.properties 에 설정 을 추가 합 니 다.
restart.include.projectcommon=/devtools-serialization-[\\w.-]+.jar
여기에 제 가 포함해 야 할 jar 패키지 의 이름 은 devtools-serialization-1.0-SNAPSHOT.jar 입 니 다.
설정 한 key 는 restart.include 로 시작 하면 됩 니 다.
restart.include.*
value 는 정규 표현 식 입 니 다.
다음 프로그램 을 다시 실행 하여 효 과 를 봅 니 다:
이상 발생 없 음
콘 솔 출력 classLoader 정 보 는?
org.springframework.boot.devtools.restart.classloader.RestartClassLoader@1d9fbdd4 DemoBean{age=null, name='null'} org.springframework.boot.devtools.restart.classloader.RestartClassLoader@1d9fbdd4
문 제 를 완벽 하 게 해결 하 다.
추가 지식:Springboot+devtools 열 배치 설정
Spring Boot 는 spring-boot-devtools 라 는 모듈 을 제공 하여 열 배 치 를 지원 합 니 다.개발 자의 개발 효율 을 향상 시 킬 수 있 습 니 다.Spring Boot 응용 프로그램 을 수 동 으로 다시 시작 하지 않 아 도 자동 으로 불 러 올 수 있 습 니 다.이전에 springboot 정적 파일 을 자동 으로 불 러 올 수 있 는 것 을 썼 습 니 다.이번 에는 원래 의 토대 위 에서 설정 을 추가 하면 springboot 프로젝트 의 열 배 치 를 실현 할 수 있 습 니 다.절 차 는 다음 과 같다.
1.pom 파일 의존 도 증가:

<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <optional>true</optional>
  </dependency>
</dependencies>
 
<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <configuration>
        <fork>true</fork> <!--  -->
      </configuration>
    </plugin>
  </plugins>
</build>
2.yml 파일 에 설정 을 추가 하여 적용:

# devtools
debug: true
spring:
 devtools:
  restart:
   enabled: true #       
 freemarker:
  cache: false  #       ,      
3,단축 키:Ctrl+Alt+S

4,단축 키:Ctrl+Shift+A,레 지 스 트 리 를 입력 하고 클릭 하여 선택:

SpringBoot 가 devtools 를 사용 하여 발생 하 는 유형 전환 이상 문 제 를 해결 하 는 것 은 바로 편집장 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.참고 하 시기 바 랍 니 다.여러분 들 도 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기