Spring 引导不会将 @Autowired 存储库注入 netty 类
Spring Boot does not inject @Autowired repository into netty classes
我有一个 Spring 引导应用程序,其结构如下:
- com.test(根Class)
- com.test.jpa(JPA 实体和存储库)
- com.test.netty(netty TCP 服务器)
根class是:
@ComponentScan(basePackages = {"com.test"})
//@EnableJpaRepositories
//@EntityScan
public class MyApplication {
...
Netty 服务器:
package com.test.netty;
@Service
@Slf4j
public class NettyServer {
private EventLoopGroup boss = new NioEventLoopGroup();
private EventLoopGroup work = new NioEventLoopGroup();
@PostConstruct
public void start() {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boss, work).channel(NioServerSocketChannel.class).localAddress(new InetSocketAddress(port))
// .option(ChannelOption.SO_BACKLOG, 1024)
.handler(new LoggingHandler(LogLevel.INFO)).childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY, true).childHandler(new ServerChannelInit());
try {
ChannelFuture future = bootstrap.bind().sync();
if (future.isSuccess()) {
log.info("Netty Server Started!");
}
} catch (InterruptedException ie) {
log.error("Error Initializing Netty Server. Error: " + ie.getMessage());
}
}
@PreDestroy
public void destroy() throws InterruptedException {
boss.shutdownGracefully().sync();
work.shutdownGracefully().sync();
log.info("Netty Server Shut Down!");
}
和:
public class ServerChannelInit extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("mainHandler", new ServiceHandler());
}
和:
package com.test.netty;
@Component
public class ServiceHandler extends ChannelInboundHandlerAdapter {
private SomeEntity en;
@Autowired
SomeRepository sr;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// Read data and persist some entitys using injected repository
和存储库:
package com.test.jpa;
//@Repository
public interface SomeRepository extends JpaRepository<SomeEntity, BigInteger> {
}
问题是:存储库没有注入 com.test.netty classes。我在 root class 和 JUnit 测试中使用它没有任何问题。
我将 @Repository 添加到存储库,并在 @EnableJPARepositories 中添加了 repo 包,但没有任何改变。
有什么想法吗?
我刚刚执行了以下内容,只需在您的主 class 中添加 @SpringBootApplication
。取消注释 @Repository
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@Repository
public interface SomeRepository extends JpaRepository<Person, BigInteger> {
void foo();
}
@Component
public class SampleRepo implements SomeRepository{
@Override
public void foo() {
System.out.println("Called...." );
}
}
@RestController
public class ServiceHandler {
@Autowired
private SomeRepository sr;
@GetMapping("/hello")
public void call(){
sr.foo();
}
}
有效!
好吧,如果您自己创建 ServiceHandler
的实例而不是使用 Spring 为您创建的 bean 实例,当然 没有依赖性将进行注射。您需要将 ServiceHandler
bean 注入 ServerChannelInit
并使 ServerChannelInit
成为 @Component
本身:
@Component
public class ServerChannelInit extends ChannelInitializer<SocketChannel>{
private final ServiceHandler handler;
public ServerChannelInit(ServiceHandler handler) {
this.handler = handler;
}
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("mainHandler", handler);
}
...
}
然后将ServerChannelInit
注入NettyServer
:
@Service
@Slf4j
public class NettyServer {
private final ServerChannelInit channelInit;
public NettyServer(ServerChannelInit channelInit) {
this.channelInit = channelInit;
}
private EventLoopGroup boss = new NioEventLoopGroup();
private EventLoopGroup work = new NioEventLoopGroup();
@PostConstruct
public void start() {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boss, work).channel(NioServerSocketChannel.class).localAddress(new InetSocketAddress(port))
// .option(ChannelOption.SO_BACKLOG, 1024)
.handler(new LoggingHandler(LogLevel.INFO)).childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY, true).childHandler(channelInit);
...
}
我有一个 Spring 引导应用程序,其结构如下:
- com.test(根Class)
- com.test.jpa(JPA 实体和存储库)
- com.test.netty(netty TCP 服务器)
根class是:
@ComponentScan(basePackages = {"com.test"})
//@EnableJpaRepositories
//@EntityScan
public class MyApplication {
...
Netty 服务器:
package com.test.netty;
@Service
@Slf4j
public class NettyServer {
private EventLoopGroup boss = new NioEventLoopGroup();
private EventLoopGroup work = new NioEventLoopGroup();
@PostConstruct
public void start() {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boss, work).channel(NioServerSocketChannel.class).localAddress(new InetSocketAddress(port))
// .option(ChannelOption.SO_BACKLOG, 1024)
.handler(new LoggingHandler(LogLevel.INFO)).childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY, true).childHandler(new ServerChannelInit());
try {
ChannelFuture future = bootstrap.bind().sync();
if (future.isSuccess()) {
log.info("Netty Server Started!");
}
} catch (InterruptedException ie) {
log.error("Error Initializing Netty Server. Error: " + ie.getMessage());
}
}
@PreDestroy
public void destroy() throws InterruptedException {
boss.shutdownGracefully().sync();
work.shutdownGracefully().sync();
log.info("Netty Server Shut Down!");
}
和:
public class ServerChannelInit extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("mainHandler", new ServiceHandler());
}
和:
package com.test.netty;
@Component
public class ServiceHandler extends ChannelInboundHandlerAdapter {
private SomeEntity en;
@Autowired
SomeRepository sr;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// Read data and persist some entitys using injected repository
和存储库:
package com.test.jpa;
//@Repository
public interface SomeRepository extends JpaRepository<SomeEntity, BigInteger> {
}
问题是:存储库没有注入 com.test.netty classes。我在 root class 和 JUnit 测试中使用它没有任何问题。 我将 @Repository 添加到存储库,并在 @EnableJPARepositories 中添加了 repo 包,但没有任何改变。
有什么想法吗?
我刚刚执行了以下内容,只需在您的主 class 中添加 @SpringBootApplication
。取消注释 @Repository
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
@Repository
public interface SomeRepository extends JpaRepository<Person, BigInteger> {
void foo();
}
@Component
public class SampleRepo implements SomeRepository{
@Override
public void foo() {
System.out.println("Called...." );
}
}
@RestController
public class ServiceHandler {
@Autowired
private SomeRepository sr;
@GetMapping("/hello")
public void call(){
sr.foo();
}
}
有效!
好吧,如果您自己创建 ServiceHandler
的实例而不是使用 Spring 为您创建的 bean 实例,当然 没有依赖性将进行注射。您需要将 ServiceHandler
bean 注入 ServerChannelInit
并使 ServerChannelInit
成为 @Component
本身:
@Component
public class ServerChannelInit extends ChannelInitializer<SocketChannel>{
private final ServiceHandler handler;
public ServerChannelInit(ServiceHandler handler) {
this.handler = handler;
}
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("mainHandler", handler);
}
...
}
然后将ServerChannelInit
注入NettyServer
:
@Service
@Slf4j
public class NettyServer {
private final ServerChannelInit channelInit;
public NettyServer(ServerChannelInit channelInit) {
this.channelInit = channelInit;
}
private EventLoopGroup boss = new NioEventLoopGroup();
private EventLoopGroup work = new NioEventLoopGroup();
@PostConstruct
public void start() {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boss, work).channel(NioServerSocketChannel.class).localAddress(new InetSocketAddress(port))
// .option(ChannelOption.SO_BACKLOG, 1024)
.handler(new LoggingHandler(LogLevel.INFO)).childOption(ChannelOption.SO_KEEPALIVE, true)
.childOption(ChannelOption.TCP_NODELAY, true).childHandler(channelInit);
...
}