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
를 통 해 주입 한다.현재 코드:
클래스 에
@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 도 나타 나 지 않 았 는데...만약 에 같은 문제 에 부 딪 힌 친구 들 이 있다 면 저 는 이것 을 선택 할 수 있 습 니 다.만약 에 큰 사람 이 그 이 유 를 알 고 있다 면 지도 해 주 실 수 있 습 니 다.