Reputation: 476
I have a Spring Boot application with the following structure:
The root class is:
@ComponentScan(basePackages = {"com.test"})
//@EnableJpaRepositories
//@EntityScan
public class MyApplication {
...
The Netty Server:
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!");
}
and:
public class ServerChannelInit extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("mainHandler", new ServiceHandler());
}
and:
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
And repository:
package com.test.jpa;
//@Repository
public interface SomeRepository extends JpaRepository<SomeEntity, BigInteger> {
}
The problem is: Repository is not injected into com.test.netty classes. I use it in root class and in JUnit tests without any problem. I added @Repository to the repository and also added repo packages in @EnableJPARepositories but nothing changed.
Any ideas?
Upvotes: 1
Views: 674
Reputation: 10716
Well, if you're creating an instance of ServiceHandler
yourself rather than using the bean instance Spring creates for you, of course no dependency injection will be performed. You need to inject the ServiceHandler
bean into ServerChannelInit
as well as make ServerChannelInit
a @Component
itself:
@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);
}
...
}
and then inject ServerChannelInit
into 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);
...
}
Upvotes: 5
Reputation: 939
I just executed with the followings, just add @SpringBootApplication
in your main class. Uncomment @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();
}
}
It works!
Upvotes: 0