1.背景
在Netty的handler中需要使用自动注入Bean,但是无法使用@Autowired注入成功,经过了解原来因为netty启动的时候并没有交给spring IOC托管。因此需要其他方法来获取注入。
2.方法
2.1 使用@PostConstruct与@Autowired
- 1、用@Component注解把类设置为组件
@Component
public class BootNettyUdpSimpleChannelInboundHandler extends SimpleChannelInboundHandler<DatagramPacket> {
}
- 2、在方法上面加@PostConstruct注解
private static BootNettyUdpSimpleChannelInboundHandler bootNettyUdpSimpleChannelInboundHandler;
@PostConstruct
public void init() {
bootNettyUdpSimpleChannelInboundHandler = this;
}
- 3、使用@Autowired
@Autowired
private SqlSessionFactory sqlSessionFactory;
- 4、使用@Autowired
bootNettyUdpSimpleChannelInboundHandler.webSocketServer.broadCastInfo(tmp);
2.2 改造Application
package com.my.equipment;
import com.my.equipment.model.BootNettyUdpServer;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Slf4j
@SpringBootApplication(scanBasePackages = {"com.my"})
@MapperScan("com.my.equipment.web.dao")
//@EnableCaching
@EnableAsync
@EnableTransactionManagement
public class Application implements CommandLineRunner , ApplicationContextAware {
private static ApplicationContext applicationContext;
private static DefaultListableBeanFactory defaultListableBeanFactory;
public static void main(String[] args) {
SpringApplication app=new SpringApplication(Application.class);
ApplicationContext context = app.run(args);
String serverPort=context.getEnvironment().getProperty("server.port");
log.info("start at http:localhost:"+serverPort);
}
@Async
@Override
public void run(String... args) throws Exception {
/**
* 使用异步注解方式启动netty udp服务端服务
*/
new BootNettyUdpServer().bind(8888);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
defaultListableBeanFactory = (DefaultListableBeanFactory)applicationContext.getAutowireCapableBeanFactory();
}
public static <T> T getBean(Class<T> clazz) {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
String className = clazz.getName();
defaultListableBeanFactory.registerBeanDefinition(className, beanDefinitionBuilder.getBeanDefinition());
return (T) applicationContext.getBean(className);
}
public static void destroy(String className){
defaultListableBeanFactory.removeBeanDefinition(className);
System.out.println("destroy " + className);
}
}
- 使用Application.getBean
WebSocketServer webSocketServer = Application.getBean(WebSocketServer.class);
webSocketServer.broadCastInfo(tmp);
Application.destroy(WebSocketServer.class.getName());