Spring Boot 学习笔记
示例代码地址:这里
1. 配置
1.1 基本配置
1.1.1 POM
1 |
|
1.1.2 application.yml
将端口设置为8080(默认就是的,并且设置tomcat的字符集为UTF-8
1 | server: |
spring boot更多预置参数请参考:
https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
示例代码地址:这里
1 | <?xml version="1.0" encoding="UTF-8"?> |
将端口设置为8080(默认就是的,并且设置tomcat的字符集为UTF-8
1 | server: |
spring boot更多预置参数请参考:
https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
GOROOT就是go的安装路径
在~/.bash_profile
中添加下面语句:
1 | GOROOT=/usr/local/go |
go install/get/run
会用到的目录。它的下面有3个文件夹:
可以设置多个子目录到GOPATH中
1 | export GOPATH=~/golib:~/goproject |
JPA: Java Persistence API 它是从EJB3中抽取出来的。
EntityManagerFactory
EntityManager
persistence.xml
@Entity
@Column
@Table
要使用JPA,我们需要添加依赖:
1 | compile group: 'javax', name: 'javaee-api', version: '7.0' |
我们来新建数据:
1 | @Entity |
然后配置数据源:
1 | @Configuration |
没有Spring的情况下,JDBC非常难用;有了Spring,JDBC就变得比较靠谱可用了。
这里我们在Bean中使用DataSource
对JdbcTemplate
进行初始化。
1 |
|
后面我们看如何配置多个DataSource
。
之前我们已经讲了@Component
,但是在实际中我们更多的遇到的是@Service
和@Repository
,@Controller
,这些其实也是@Component
。
首先我们来添加一些依赖:
1 | dependencies { |
注意这里我们用了返回,这是因为需要对应的驱动
ACID 属性:
Atomic原子:All or Nothing
Consistent一致性: DB integrity constraints never violated
Isolated: How transactions see work done by others
Durable: Committed changes are permanent
我们一般是在Service层声明事务。
@Transactional
注解允许我们管理一个事务管理器。Spring不直接提供事务管理器,它提供一个hook连接到已经存在的事务管理器,比如我们使用关系数据库,那Spring就是使用关系数据库的事务管理器。Spring的Bean和Entity允许我们请求事务管理器,设置属性(比如超时、只读等)。
应用Spring的事务需要两步:
Spring的一个特点是测试Component非常方便。
现在我们为BaseballGame
创建BaseballGameTest
。然后做测试:
1 | public class BaseballGameTest { |
这里每次测试的时候,都要调用一次setUp
,也就是我们的ApplicationContext
会被反复创建很多次,Spring提供了一些方法让ApplicationContext
只执行一次。
1 | @RunWith(SpringJUnit4ClassRunner.class) // |
这里我们用@RunWith(SpringJUnit4ClassRunner.class)
和@ContextConfiguration(classes = AppConfig.class)
让我们可以直接用Bean和ApplicationContext
。
事务测试是当测试完成后,所有的测试操作都会回滚。我们用@Transactional
来表示事务测试。
1 | @RunWith(SpringJUnit4ClassRunner.class) |
AOP适用于以下场景:代码交织(code tangling)和代码分散(code scattering)
代码交织是指一个方法完成多个功能,这几个功能之间又没有必然联系,比如我们需要做日志、检查授权和执行业务逻辑,如果我们不用AOP的话那这三个就混在一起了。
代码分散式指比如我们有多处需要做日志,然后这些代码在多个地方重复。
AOP允许我们将这些动作封装成一个类,然后告诉Spring我们希望在多个地方调用这个类(成为Aspect),从而避免代码交织和分散。
AOP会设计到一下几个概念:
连接点,指的是我们能够应用我们Aspect的地方。这是告诉我们where to use the Aspects.
在一般概念的AOP上,我们可以在任何地方用Aspect,但是Spring对这一规则做了限制,我们只能用在Spring管理的Bean的公共方法中。
切入点一般来说可以认为和连接点类似。表示我们实际声明的连接点。
之前我们基于注解的配置是这样的:
1 | @Configuration |
我们知道如果没有@Qualifier
注解,就会报错。但是如果我们把home
和away
去掉,然后添加一个集合,像下面这样:
1 | ... |
如果我们有多个相同类型的Bean,但是是以单个变量声明的,如
1 | @Autowired @Qualifier("redSox") |
如果没有@Qualifier
注解就会报错,但是想前面例子是用集合的形式:
1 | @Autowired |
就不会报错,他会扫描所有这个类型的Bean,然后放到集合中。
这里,我们用Gradle创建Spring的应用。
1 | group 'lx.spring.core' |
spring希望我们尽可能的使用接口,因此,我们声明,Team
, Game
接口,然后创建对应的实现:
1 | public interface Team { |
对应的实现类:
1 | public class Cubs implements Team { |
本章包含:
Channel
, EventLoop
, 和 ChannelFuture
ChannelHandler
和 ChannelPipeline
Channel
, EventLoop
和ChannelFuture
可以看成是Netty对网络的抽象:
Channel
:Socket
EventLoop
: 控制流、多线程和并发ChannelFuture
:异步通知基本IO操作(bind()
, connect()
, read()
, write()
)依赖于底层网络传输。在基于Java的网络中,基础组成是Socket
类。Netty的Channel
接口提供了的API能大幅度减少直接操作Socket
的复杂度。此外,Channel
是所有扩展类的根类。下面是一些继承的类:
EmbeddedChannel
LocalServerChannel
NioDatagramChannel
NioSctpChannel
NioSocketChannel
EventLoop
定义了Netty对连接生命区间事件处理的核心抽象。在后面的章节里我们会讨论EventLoop
的细节。下图展示了Channel
, EventLoop
, Thread
和EventLoopGroup
之间的关系。