spring in action 4th --- quick start
读spring in action.
- 环境搭建
- quick-start依赖注入
- 面向切面
1.环境搭建
- jdk1.8
- gradle 2.12
- Intelij idea 2016.2.1
1.1创建一个gradle项目
在idea中,new -> project -> gradle 创建一个空项目。创建成功后修改build.gradle :
group 'com.test'
version '1.0-SNAPSHOT' apply plugin: 'java'
apply plugin: 'war' sourceCompatibility = 1.8
targetCompatibility = 1.8 repositories {
mavenLocal()
mavenCentral()
} dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11' }
根目录下创建.gitignore:
# Created by .ignore support plugin (hsz.mobi)
.idea/
.gradle/
build/
out/
*/build/
1.2 quick start
spring的核心是依赖注入,那么简单的做一个入门测试。
在项目名上右键,new->module->gradle->创建一个java项目quick-start. 修改生产的build.gradle:
group 'com.test'
version '1.0-SNAPSHOT' apply plugin: 'java' sourceCompatibility = 1.8 repositories {
mavenLocal()
mavenCentral()
} dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11' compile 'org.springframework:spring-context:4.3.2.RELEASE'
}
这里参考:http://projects.spring.io/spring-framework/#quick-start 的案例.
在quick-start module下创建一个package src/main/java,在java文件夹上右键,Mark Directory as -> Sources Root.
这时候idea的项目配置还没有刷新,需要手动点击一下刷新:
这时候,idea就可以resolve quick-start这个项目以及他的dependency了。
添加spring-context会添加其他依赖:
dependencies {
compile 'org.springframework:spring-context:4.3.2.RELEASE'
}
1.2.1 Hello World
我们来创建打印消息的组件。MessagePrinter打印一个MessageService的实例的信息。:
创建接口com.test.hello.MessageService:
package com.test.hello; /**
* Created by rmiao on 8/15/2016.
*/
public interface MessageService {
String getMessage();
}
创建组件com.test.hello.MessagePrinter:
package com.test.hello; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; /**
* Created by rmiao on 8/15/2016.
*/
@Component
public class MessagePrinter { final private MessageService service; @Autowired
public MessagePrinter(MessageService service){
this.service = service;
} public void printMessage(){
System.out.println(this.service.getMessage());
}
}
@Component声明MessagePrinter是一个bean,由spring容器来管理。
@Autowired 这里是构造器注入,会根据构造器参数的类型和参数名来将spring容器中的bean注入构造器。
针对MessagePrinter的注入参数,我们需要一个MessageService的实现:
MessageService mockMessageService(){
return () -> "Hello World!";
}
下面开始启动spring容器来测试这个打印消息组件:
创建com.test.hello.Application:
package com.test.hello; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration; /**
* Created by rmiao on 8/15/2016.
*/
@Configuration
@ComponentScan
public class Application { @Bean
MessageService mockMessageService(){
return () -> "Hello World!";
} public static void main(String[] args){
ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
MessagePrinter printer = context.getBean(MessagePrinter.class);
printer.printMessage();
}
}
@Configuration来声明Application是一个配置类,相当于xml配置文件。这里只配置了一个bean mockMessageService.
@Bean 用来声明一个bean并交由spring容器管理。相当于xml配置文件中<bean>. 这种方式表示声明一个MessageService的类的bean,bean id为mockMessageService。
@ComponentScan来声明spring容器扫描范围,这种方式表示扫描Application所在包以及子包下的所有类,然后将识别到的bean放到spring容器中。
AnnotationConfigApplicationContext用来创建spring容器。getBean来获取容器中的bean。
最终,打印Hello World!
1.2.2 Aop面向切面
spring的另一个强大特性是面向切面编程。可以在任意方法的调用前后进行一些操作。比如记录日志:
添加aop依赖:
dependencies { compile group: 'org.springframework', name: 'spring-aop', version: '4.3.2.RELEASE'
compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.8.9' }
添加logback日志组件依赖:
dependencies { compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.21'
compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.1.7'
compile group: 'ch.qos.logback', name: 'logback-core', version: '1.1.7'
compile group: 'org.codehaus.groovy', name: 'groovy', version: '2.4.7' }
在src/main/resources下创建logback.groovy:
import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.core.ConsoleAppender
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy
import ch.qos.logback.core.rolling.RollingFileAppender
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy import static ch.qos.logback.classic.Level.DEBUG
import static ch.qos.logback.classic.Level.INFO appender("STDOUT", ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n"
}
}
appender("FILE", RollingFileAppender){
file = "quick-start/log/project.log"
encoder(PatternLayoutEncoder) {
pattern = "%d{yyyy-MM-dd_HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
}
rollingPolicy(FixedWindowRollingPolicy) {
fileNamePattern = "quick-start/log/project.%i.log.zip"
minIndex = 1
maxIndex = 10
}
triggeringPolicy(SizeBasedTriggeringPolicy) {
maxFileSize = "2MB"
}
} // specify level
logger("com.test.hello", DEBUG)
//By default, the level of the root level is set to DEBUG
root(DEBUG, ["STDOUT"])
下面开始面相切面编程。
我们想要在消息打印组件的前后做一些工作,但又不想要修改打印组件的内容。那么可以使用@Aspect:
创建:com.test.hello.Monitor.java:
package com.test.hello; import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; /**
* Created by rmiao on 8/15/2016.
*/
@Aspect
@Component
public class Monitor { private final Logger logger = LoggerFactory.getLogger(Monitor.class); @Pointcut("execution(* com.test.hello.MessagePrinter.printMessage())")
public void message(){} @Before(value = "message()")
public void pre(){
logger.info("before print.");
} @After(value = "message()")
public void after(){
logger.info("after print.");
} }
@Aspect表示这是一个aop切面。等价于xml配置中的<aop>
@Pointcut表示切面的匹配方式
@Before表示切面调用前执行
@After表示切面调用后执行。
要使上述的配置生效,还需开启切面,在配置类中声明@EnableAspectJAutoProxy:
package com.test.hello; import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.*; /**
* Created by rmiao on 8/15/2016.
*/
@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class Application { @Bean
MessageService mockMessageService(){
return () -> "Hello World!";
} public static void main(String[] args){
ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
MessagePrinter printer = context.getBean(MessagePrinter.class);
printer.printMessage();
}
}
运行:
八月 15, 2016 9:13:45 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@31cefde0: startup date [Mon Aug 15 21:13:45 CST 2016]; root of context hierarchy
21:13:49.278 [main] INFO c.t.h.Monitor - before print.
Hello World!
21:13:49.306 [main] INFO c.t.h.Monitor - after print.
spring in action 4th --- quick start的更多相关文章
- 1、Spring In Action 4th笔记(1)
Spring In Action 4th笔记(1) 2016-12-28 1.Spring是一个框架,致力于减轻JEE的开发,它有4个特点: 1.1 基于POJO(Plain Ordinary Jav ...
- Spring in Action 4th 学习笔记 之 AOP
前提:本文中的AOP仅限于Spring AOP. 先说说为什么需要AOP 最简单的一个例子就是日志记录,如果想记录一些方法的执行情况,最笨的办法就是修改每一个需要记录的方法.但这,真的很笨... 好的 ...
- Spring in Action 4th 学习笔记
约定: 一.@Xxx Class 表示被@Xxx注解的类.同理还有@Xxx注解的字段或方法. 例如:@Bean Method. 二.@Component Class 同时代指 @Controller. ...
- ssh整合随笔(注解方式,Spring 管理action)
Web.xml<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=" ...
- Spring in action记录
最近一段时间重新学习了一遍SPRING,现在对这些笔记整理一下,一来算是对之前的学习有一个交代,二来当是重新学习一次,三来可以留下备份 这次学习中以SPRING IN ACTION 4这学习资料,整书 ...
- 学习spring in action 第一天
这段时间,开始学习java吧,因为C sharp 学习了java的大量语法格式,所以,留意下,就不会错了,java 有的c sharp也有,而且之前我也学习过java的桌面开发,但是一下子上来就要自己 ...
- spring in action学习笔记十五:配置DispatcherServlet和ContextLoaderListener的几种方式。
在spring in action中论述了:DispatcherServlet和ContextLoaderListener的关系,简言之就是DispatcherServlet是用于加载web层的组件的 ...
- spring in action 学习笔记十四:用纯注解的方式实现spring mvc
在讲用纯注解的方式实现springmvc之前先介绍一个类:AbstractAnnotationDispatcherServletInitializer.这个类的作用是:任何一个类继承AbstractA ...
- spring in action 学习十一:property placeholder Xml方式实现避免注入外部属性硬代码化
这里用到了placeholder特有的一个语言或者将表达形式:${},spring in action 描述如下: In spring wiring ,placeholder values are p ...
随机推荐
- Python swapcase()方法
首先,要明白Python swapcase() 方法用于对字符串的大小写字母进行转换. 其次,了解swapcase()方法语法:str.swapcase() 返回值:返回大小写字母转换后生成的新字符串 ...
- HW2016_字符串_STL_DP
一.在字符串str1中删除那些在str2中出现的字符. str2可能会有重复字符,直接遍历会导致效率低下,故先借助STL的set容器对str1查重: 然后,遍历str1和str2,对str1进行查重. ...
- canvas初探1
刚申请的博客,当然这也是第一篇.对于canvas也是刚开始着手进行学习,有哪些不对的地方,还望看到本篇博文的朋友指正. 1.canvas的历史 首先,它是HTML5的一个标签. 它是为了客户端矢量图形 ...
- Ubuntu添加开机自动启动程序方法
1. 开机启动时自动运行程序 Linux加载后, 它将初始化硬件和设备驱动, 然后运行第一个进程init.init根据配置 文件继续引导过程,启动其它进程.通常情况下,修改放置在 / ...
- CoreData教程
网上关于CoreData的教程能搜到不少,但很多都是点到即止,真正实用的部分都没有讲到,而基本不需要的地方又讲了太多,所以我打算根据我的使用情况写这么一篇实用教程.内容将包括:创建entity.创建r ...
- Android开发学习之路-提升用户体验小技巧
记得之前看谷歌的一个视频提到这个用户体验的问题,今天想起来了就写了个Demo来记录下. 当一个事件发生之后,用户需要一段时间才能知道结果,那么这段时间究竟应该让用户干什么?这个问题很常见,比如我们的软 ...
- 使用Ldoc给Lua生成文档
Ldoc介绍 LDoc是一个Lua的文档生成工具,过去,比较常用的Lua生成文档的工具是LuaDoc,可惜作者自从2008年之后就再也没有发布过新的版本了,说明作者基本上已经放弃维护了.而LDoc则是 ...
- Oralce 重建EM服务,OracleDBConsoleOracle
今天打开Oracle ,想进em看看,结果发现OracleDBConsoleOracle服务老是报错: OracleDBConsoleOracle 服务因 2 (0x2) 服务性错误而停止. 搞不懂, ...
- 考勤系统代码分析——主页布局easyui框架
考勤系统主页的布局用的是easyui的Layout控件 Layout:布局容器有5个区域:北.南.东.西和中间.中间区域面板是必须的,边缘的面板都是可选的.每个边缘区域面板都可以通过拖拽其边框改变大小 ...
- show master/slave status求根溯源
show master/slave status分别是查看主数据库以及副数据库的状态,是一种能查看主从复制运行情况的方式. 这里仅仅讨论linux下的nysql5.7.13版本的执行情况 一.show ...