Spring 零配置并解决Log日志

 Spring2.X的时候配置文件一直采用了XML的配置方式,3.X之后引入了注解配置的方式,这样大大的减少了我们配置文件的书写,而且以前XML中很多都是模板性的东西。但是一直到现在才真正的理解和能够使用Spring中提倡的0配置,下面我们用一个实例来详细说明这种配置方式的使用。

1. 添加依赖

 创建一个MAVEN的项目,在里面加入Spring的依赖,毕竟我们要用它嘛,我们使用的版本是 4.2.9.RELEASE 。
<pre>
<properties>
<spring.version>4.2.9.RELEASE</spring.version>
</properties>
<dependencies>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependencies>
</pre>

2. 逻辑代码

 在项目开发中,以前的时候我们连接数据库或者配置端口等的时候,我们一般都采用属性配置文件的方式来记录内容,然后在代码中读取出来,进行设置。这个过程当中我们还需要把读出来的内容进行类型转换等一系列的操作,这是每一个项目必不可少的一样工作,Spring中就有现成的属性文件读取转换的操作,我们使用的时候只要按照它的方式来就可以很轻松的实现属性文件的读取,我们就以Spring的的属性文件读取来举例。

2.1 属性文件

 属性文件放在MAVEN项目的 <b>resources</b> 文件夹下面,其实也就是对应了类路径,加载的时候我们可以使用 <b>classpath:</b>就进行读取了,属性文件有两人个类型的内容,一个是 <b>String</b> 类型的<b>name</b>,另一个是 <b>Int</b> 类型的 <b>age</b>,如下:
<pre>
# 文件名是 App.properties
app.name=MyName
app.age=23
</pre>

2.2 属性占位配置类

 Spring中对属性文件的操作采用面向对象的方式来进行,属性文件在Spring中也是对就了一个类文件(特殊类文件)。它用注解 <b>@Configuration</b>和<b>@PropertySource</b>来标记,并且在里面返回一个<b>@Bean</b>标记的对象。
<pre>
@Configuration // 这个不是必须的,但是Spring的源码中提倡两个配合使用
@PropertySource("classpath:App.properties") // 这儿引入属性文件
public class PropertyPlaceholderConfig {
// PropertySourcesPlaceholderConfigurer 这是Spring中的一个属性点位实现类
// 这是模板化的使用方式
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
</pre>

2.3 属性内容使用

 属性文件已经配置好,接下来就是如何使用它,下面有一个服务类,它里面需要引入我属性文件中对应的值来进行处理。首先我们需要用一个注解<b>@Import</b>来引入属性点位类文件,然后再用<b>@Value</b>注解来根据属性名注入对应的属性值。
<pre>
@Component // 这个注解用于让Spring扫描之后,生成对应的Bean
@Import(PropertyPlaceholderConfig.class) // 引入占位属性类
public class AppService {
// 这是log4j日志文件的使用方式,在下面介绍
private static final Logger log = LoggerFactory.getLogger(AppService.class);

// 根据属性名装配值
@Value("${app.name}")
private String name;

// 装配并进行类型转换
@Value("${app.age}")
private int age;

public void showProperties(){
    // 日志输出
    log.debug(getClass().getSimpleName());
    // 属性显示
    System.out.println("Name:"+name);
    System.out.println("Age:"+age);
}

}
</pre>

3. 运行项目

 上面的配置已经完成,下面我们就来启动Spring,测试项目的支行效果。Spring启动也是不是一件简单的事情,我们首先要指定它的配置文件,以前我们当然是指定<b>XMl</b>文件,但是现在我们是 0配置 ,所以方式当然不一样了。

3.1 配置文件

 0配置并不是说没有配置文件,只是没有以前的<b>xml</b>配置文件了而已,但是我们要自定义一个类,来作为Spring的配置文件,只是这个类采用注解进行标记了而已。
<pre>
@Configuration // 标记它是一个配置文件
@ComponentScan(basePackages = {"com.outlook.sftjun"})
// 指定Spring从什么位置开始扫描,然后初始化Bean对象,进行在容器中进行注入
// 扫描是扫描指定的包及其 子包
public class AppConfig {
// TODO ...
// 独立出配置文件,个人认为是最好的方式
}
</pre>

3.2 启动容器

 万事俱备,只欠运行。让我们用下面的代码来运行,检验一下,我们的设置是否正确。
<pre>
@ComponentScan(basePackageClasses = {AppConfig.class})
// 指定了配置文件的是 AppConfig.class
// 当然,这儿也可以不用这种方式进行配置
// 直接使用 @ComponentScan,它也会从当前包开始
// 向子包进行扫描,从而“减少”一个配置文件
public class App {
private static final Logger log = LoggerFactory.getLogger(App.class);

public static void main(String[] args) {
    log.debug("Start spring ....");
    // 启动容器
    // 里面指定是使用当然类,但是当前类又指定到了 AppConfig.class
    // 最终还是 AppConfig.class
    ApplicationContext context = new AnnotationConfigApplicationContext(
            App.class);
    //  取得对象并输出属性文件
    context.getBean(AppService.class).showProperties();
}

}
</pre>

4. 显示结果

 上面的步骤都没有问题的话,我们就可以从控制台看见下面的代码:
<pre>
Name:MyName
Age:23
</pre>

5. 测试

 当然上面的启动容器来进行测试,并不是最好的方式,如果项目大的话,启动也得花很长时间,这样就显得没有什么效率了。值得一提的是Spring提供了一个<b>Test</b>框架给我们使用。方式如下:

  • 添加依赖
    <pre>
    <junit.version>4.12</junit.version>

    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>${spring.version}</version>
    </dependency>

    <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>${junit.version}</version>
    </dependency>

    </pre>

  • 指定配置文件
    <pre>
    // 采用这个注解,JUnit 就会 invoke 标准了该注解的类
    @RunWith(SpringJUnit4ClassRunner.class)
    // 指定Spring 的相关配置
    @ContextConfiguration(classes = {AppConfig.class})
    public class AppTest {
    // 注入我们需要使用的类
    @Autowired AppService appService;

    @Test
    public void tst(){
    appService.showProperties();
    }
    }
    </pre>

  • 执行测试
     运行单元测试之后,我们会看到和上面启动容器时相同的结果。
    <pre>
    Name:MyName
    Age:23
    </pre>

6. 集成日志

 上面我们的类中使用了 <b>Logger</b> 这个类来进行日志处理,但是这个东西又是从何而来呢,那就是下面我们要说的东西。Spring 中采用的是日志框架 <b>slf4j</b> ,若我们没有引入日志的话,我们每次运行都会看到警告(长什么样子,我就不贴了,大家对比一下就看见了),但是这个框架本身不具备日志功能,还需要和其它的具备日志功能的第三方进行配置使用,<b>log4j</b> 是一个不错的选择。

6.1 引入依赖

 当然了,用人家的东西,当然要先把东西拿到手了,不然怎么用,下面我们就引入日志相关的包。
<pre>
<slf4j.version>1.7.22</slf4j.version>
<log4j.version>1.2.17</log4j.version>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
</pre>

6.2 指定配置文件

 拿到东西了,我们当然还要告诉人家做什么,不然有什么用。 <b>log4j</b> 的配置文件,约定叫 <b>log4j.properties</b> ,位置类路径下面,内容如下:
<pre>
#config root logger
log4j.rootLogger = DEBUG,stdout
#表示Logger不会在父Logger的appender里输出
log4j.additivity.org.apache=true
# standout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d (%p) [%c] - %m%n
</pre>
 完整的配置文件有很多种方式,这儿就使用控制台输出这种方式,日志级别就指定为 <b>Debug</b>级别。若需要完整的多方式配置的详细文件,评论区找我。

6.3 使用方式

 使用方式非常简单,只需要指定输出的级别就可以了,常用方式如下。
<pre>
// 得到日志
private static final Logger log = LoggerFactory.getLogger(AppService.class);
// 输出内容
log.debug(“需要输出的内容”);// 这儿的日志输出级别是 debug
</pre>
 完成这些配置之后,我们在启动Spring就不会出现警告了,而且发布项目之后,修改日志输出方式,它可以把程序运行的日志按级别输出到文件,数据库等。

7. 总结

  • 版本问题
     使用Spring 0配置的时候,要注意使用的Spring的版本,如果版本太低了,当然不支持这种方式了,但是也不能太高,新版本有很多的变化,我在写Demo的时候,采用了高版本的,就遇到了注解无法诱导出来的情况,弄了好长时间才发现是这个问题。
  • 测试问题
     因为测试的时候使用了注解,并采用了框架,它是使用反射和代理来实现的,我并没有研究它是怎么写的,但是当你的测试方法不是使用<b>public</b>修饰的情况下,那就会给你一个惊喜了,而且你还不知道问题是出在哪儿,所以测试中的方法要用<b>public</b>修饰符进行修饰,不知道以后的版本中还会不会有这个限制。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容