您的位置:首页 > 编程语言 > Java开发

spring-netty-Mybatis框架的jar应用注解开发遇见的问题和解决方案

2018-01-16 10:17 776 查看

说明

新手来的.不足之处请指正. 因为之前没有接触过配置注解开发, 也没怎么配置过spring-Mybatis. 碰见了很多坑.

在折腾了很久之后解决了. 分享出来给大家做(骗)贡(点)献(击)

开始

pom就不放了, 全球通用. 配置也放了一些主要的. 做之前也是参考了很多网上大佬的帖子, 如有雷同.

(程序员的事怎么能叫抄呢)

配置文件

<description>Spring公共配置</description>
<context:annotation-config />
<!-- 这里是给出需要扫描的包的路径,一般是最外层. 表明使用annotation 自动注册bean,并检查@Required,@Autowired等属性并注入 -->
<context:component-scan base-package="com.mid.abc" />

<!-- 启动端口 -->
<!-- 这里因为是jar应用.所以提供了一个启动器 -->
<bean id="initServer" class="com.mid.abc.start.InitServer">
<property name="port" value="端口" />
</bean>

<!-- spring和MyBatis整合,不使用mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 自动扫描mapping.xml文件,**表示迭代查找 -->
<property name="mapperLocations" value="classpath:mybatis/*.xml" />
</bean>

<!-- DAO接口所在包名,Spring会自动查找其下的类 ,包下的类需要使用@MapperScan注解,否则容器注入会失败 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mid.abc.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>

<!-- 事务管理器, Jdbc单数据源事务 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>

<!-- 使用annotation定义事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />

<!-- 之前一直不能注入, 加了这句就没问题了不知道为什么. -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<aop:config>
<!-- 这里的路径是再service包下还有一层文件夹(service.xxx.xxxService.java) -->
<aop:advisor pointcut="execution(* com.mid.abc.service.*..*.*(..))"
advice-ref="txAdvice" />
</aop:config>


代码问题

因为是改的祖传老代码. 所以真的是呕心沥血.

new对象的问题

在启动器(或者web项目的Controller里)有需要new的对象.然而这个对象中有需要注入的bean.那么这个对象最好也要注入.否则会报null.

原理其实就是new出来的对象是在注入之后.里面的bean就不受spring管理了.如下:

/**
* 服务启动
*
* @throws Exception
*/
public void run() throws Exception {

log.info("Server Start......");

// EventLoopGroup是用来处理IO操作的多线程事件循环器
// bossGroup 用来接收进来的连接
EventLoopGroup bossGroup = new NioEventLoopGroup();
// workerGroup 用来处理已经被接收的连
4000
接
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
// 启动 NIO 服务的辅助启动类
ServerBootstrap b = new ServerBootstrap();
log.info("Init Channel......");
b.group(bossGroup, workerGroup)
// 配置 Channel
.channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
// 注册handler
ch.pipeline().addLast(new ServerHandler());
}
}).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);

log.info("Exposed IP Address: " + java.net.InetAddress.getLocalHost().getHostAddress());
log.info("Binding On Port {} ......", port);
// 绑定端口,开始接收进来的连接
ChannelFuture f = b.bind(port).sync();
// 等待服务器 socket 关闭 。
f.channel().closeFuture().sync();
} finally {
log.info("Shutdown Server......");
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}


以上代码的new ServerHandler()中需要注入消息操作.那这个new就很不合适.

修改为如下就可以了.

@Component
public class InitServer {
...
@Autowired
private ServerHandler serverHandler;
...
// 注册handler
ch.pipeline().addLast(serverHandler);
...
}


就是这里需要配置增加
不知道为什么. 想不通.


abstract类注入

abstract类中需要注入的属性.

抽象类是无法实例化的, 所以无法注入bean. 因此需要在抽象类的子类中注入该属性, 再传递给父类, 而父类是不需要加什么注解的.如下:

// 这是父类
public abstract class Processor {
protected IDontKnowHer iDontKnowHer;
}

// 这是子类
@Service
public class MessageProcessor extends Processor {
//这里使用的init方法在autowired的作用下就会被优先调用并注入属性.传递bean给父类使用.
@Autowired
public void init(IDontKnowHer iDontKnowHer){
super.iDontKnowHer = iDontKnowHer;
}
}


以后有相关问题和解决方案也会更新在这里.

以上问题如果有更好的解决方案请留言.

非常感谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐