netty&springboot 프로젝트 에서 autowired 주입 실패 문제

13808 단어 채굴 기록
문제 설명
배경:프로젝트 는 netty 로 통신 합 니 다.springboot 기능 을 사용 하지 않 았 습 니 다.시작 할 때 주 방법 에 스 레 드 가 생 성 되 어 있 습 니 다.new 를 통 해 channel 감청 포트 를 만 듭 니 다.
public class RunServer {
    public static void main(String[] args) {
        Runnable task1 = () -> {
            TcpServer server = new TcpServer();
            try {
                server.start(new InetSocketAddress(ServerConfig.TCP_PORT));
            } catch (InterruptedException e) {
                e.printStackTrace();
                System.out.println("  TCP     ");
            }
        };

        ExecutorService fixedThreadPool = new ThreadPoolExecutor(2, 2,
                0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>(2));
        fixedThreadPool.execute(task1);
    }

지금부터 프로젝트 를 springboot 프로젝트 로 재 구성 하고 메 일과 redis 기능 을 통합 합 니 다.
여 기 는 부분 코드 입 니 다.
public class ServerHandler  extends SimpleChannelInboundHandler {
    private final StringBuffer buffer = new StringBuffer(1000);

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private EmailSend  emailSend;
    @Autowired
    private DataForIOTConstant dataForIOTConstant;


결 과 는 기능 을 실현 하지 못 했다.
문제 분석
여기 서 우 리 는 전통 적 으로 netty 와 springboot 를 사용 하여 netty 를 통합 하 는 차 이 를 말 해 야 한다.전통 적 으로 netty 를 사용 할 때 우 리 는 이렇게 boottstrap 을 초기 화 합 니 다.
 serverBootstrap
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new ChannelServerHandler());

여기 주의childHandler(new ChannelServerHandler())는 new 를 통 해 대상 을 얻 었 고 우리 spring boot 는 자동 으로 주입 하여 사용 합 니 다@Autowired.
springboot 의 시작 을 회상 합 니 다.그 는 bean 을 스 캔 하여 autoconfiguration 을 통 해 설 정 된 properties 를 bean 인 스 턴 스 에 주입 하고 이 bean 을 IOC 용기 에 위탁 하 겠 다 고 말 했 습 니 다.
우리 가 어떤 bean 이 필요 할 때@Autowired를 통 해 주입 한다.
현재 코드:
  • spring boot 에 위탁 하지 않 고 스 캔
  • bean 이 되 지 않 고 IOC 에 맡 겨 관리
  • 문제 해결
    클래스 에@Component를 더 하면 모든 대상 이 autowired 를 통 해 주입 되 며 new 를 사용 할 수 없습니다.
    소결:
    springboot 을 사용 할 때 스 캔 된 bean 만 초기 화 되 고 초기 화 된 bean 만 IOC 용기 에 가입 할 수 있 으 며,IOC 에 가입 한 bean 만 사용 할 수 있 습 니 다autowired.
    배치 할 때 또 문제 가 생 겼 어 요.
    질문 설명:
    우선 프로젝트 는 ide(저 는 아이디어)에서 뛰 는 것 은 문제 가 없 지만 jar 로 배 치 될 때 빈 지침 을 확보 합 니 다.
    빈 포인터 의 대상 찾기:
    /*
            ConfigurationProperties properties       ,    bean               ,       。
    */
    @Component
    @Data
    @ConfigurationProperties(prefix = "iot.constant")
    public class DataForIOTConstant  implements InitializingBean {
        private String url;
        private String dataAddress;
        private String apiKey;
        private Integer tcpPost;
        
         private String URL_CONSTANT;
        private String DATA_ADDRESS_CONSTANT;
        private String API_KEY_CONSTANT;
        private Integer TCP_POST_CONSTANT;
        
        @Override
        public void afterPropertiesSet() throws Exception {
            URL_CONSTANT = url;
            DATA_ADDRESS_CONSTANT = dataAddress;
            API_KEY_CONSTANT = apiKey;
            TCP_POST_CONSTANT = tcpPost;
    
            System.out.println(URL_CONSTANT);
            System.out.println(DATA_ADDRESS_CONSTANT);
            System.out.println(API_KEY_CONSTANT);
            System.out.println(TCP_POST_CONSTANT);
        }
    

    문제 분석:
    먼저 이 방법 을 말씀 드 리 겠 습 니 다.네트워크 프로 그래 밍 에서 이 방법 은 사용 할 수 있 습 니 다.ConfigurationProperties을 통 해 properties 의 속성 을 속성 에 넣 을 수 있 습 니 다.static 는 주입 방식 으로 값 을 얻 을 수 없 기 때문에 특정한 노드 에서 만 값 을 부여 할 수 있 습 니 다.이것 은 우리 에 게 속성 이 이미 왔 다 는 것 을 요구한다.그래서 우 리 는InitializingBean을 사용 하여 bean 이 초기 화 된 후에 값 을 부여 합 니 다.
    일반적인 네트워크 프로 그래 밍 은 상 관 없 지만 이 프로젝트 는 자바 웹 프로젝트 가 아 닙 니 다.시작 한 후에 어떤 포트 를 감청 하고 데 이 터 를 기다 리 며 분석 하 는 것 입 니 다.이것 은 netty 를 사용 합 니 다.
    이 는 프로젝트 가 시 작 될 때 시작 순 서 를 주의해 야 한 다 는 뜻 이다.InitializingBean를 사용 하면 우아 하 게 호출 할 수 있 지만 시작 할 때 포트 를 감청 하려 면 속성 값 이 필요 한 방법 은 적절 하지 않다.
    // DataForIOTConstant.TCP_POST_CONSTANT          
    channelFuture = serverBootstrap.bind(DataForIOTConstant.TCP_POST_CONSTANT).sync();
    Log.get().info("     {},      ",dataForIOTConstant.getTcpPost());
    

    문제 해결
    사용 포기InitializingBean,get 을 통 해 속성 치 를 직접 호출 하면 됩 니 다.
    소결:
    아이디어 와 jar 의 작 동 에 따라 개발 에 문제 가 없 었 고 배치 할 때 빈 포인터 가 생 겼 습 니 다.
    즉,아 이 디 어 는 모든 bean 인 스 턴 스 를 초기 화하 고 호출 방법 을 시작 하 는 것 입 니 다.(이렇게 하면 속성 이 비어 있 는 상황 이 나타 나 지 않 습 니 다).
    jar 패키지 가 시작 되 었 습 니 다.bean 의 초기 화 는 마지막 에 두 었 습 니 다.
    후기:소 편 은 총 결 을 쓸 때 모 의 bug 는 재현 되 지 않 았 다.그리고 원래 빈 포인터 의 error 도 나타 나 지 않 았 는데...만약 에 같은 문제 에 부 딪 힌 친구 들 이 있다 면 저 는 이것 을 선택 할 수 있 습 니 다.만약 에 큰 사람 이 그 이 유 를 알 고 있다 면 지도 해 주 실 수 있 습 니 다.

    좋은 웹페이지 즐겨찾기