Java web——日志系统+Javabean和spring中的bean

一、日志框架的分类

  • 门面型日志框架:
    • JCL:一套Java日志接口(Apache基金会所属的项目)
    • SLF4J:  是一套简易Java日志门面,本身并无日志的实现
  • 记录型日志框架:
    • JUL(JDKLog、jdk-logging):JDK中的日志记录工具,自Java1.4以来的官方日志实现
    • Log4j:一个具体的日志实现框架
    • Log4j2:一个具体的日志实现框架,LOG4J1的下一版本,Log4j 2不兼容Log4j 1
    • Logback:一个具体的日志实现框架,和Slf4j是同一个作者,但其性能更好

二、发展历程

1.Log4j

  • 在JDK 1.3及以前,Java打日志依赖System.out.println(), System.err.println()或者e.printStackTrace(),Debug日志被写到STDOUT流,错误日志被写到STDERR流

  • 这样打日志有一个非常大的缺陷,即无法定制化,且日志粒度不够细。

  • 于是, Gülcü 于2001年发布了Log4j。Log4j 在设计上非常优秀,对后续的 Java Log 框架有长久而深远的影响,它定义的Logger、Appender、Level等概念如今已经被广泛使用

  • Log4j 的短板在于性能,在Logback 和 Log4j2 出来之后,Log4j的使用也减少了

2.JUL

  • 受Log4j启发,Sun在Java1.4版本中引入了java.util.logging(JUL),但是JUL功能远不如log4j完善,开发者需要自己编写Appenders(Sun称之为Handlers),且只有两个Handlers可用(Console和File),JUL在Java1.5以后性能和可用性才有所提升。

3.JCL(commons-logging)

  • 由于项目的日志打印必然选择两个框架中至少一个,这时候,Apache的JCL(commons-logging)诞生了。JCL 是一个Log Facade,只提供 Log API,不提供实现,然后有 Adapter 来使用 Log4j 或者 JUL 作为Log Implementation
  • 在程序中日志创建和记录都是用JCL中的接口,在真正运行时,会看当前ClassPath中有什么实现,如果有Log4j 就是用 Log4j, 如果啥都没有就是用 JDK 的 JUL。 这样,在你的项目中,还有第三方的项目中,大家记录日志都使用 JCL 的接口,然后最终运行程序时,可以按照自己的需求(或者喜好)来选择使用合适的Log Implementation。如果用Log4j, 就添加 Log4j 的jar包进去,然后写一个 Log4j 的配置文件;如果喜欢用JUL,就只需要写个 JUL 的配置文件。如果有其他的新的日志库出现,也只需要它提供一个Adapter,运行的时候把这个日志库的 jar 包加进去
  • 不过,JCL对Log4j和JUL的配置问题兼容的并不好,使用JCL还可能会遇到类加载问题,导致NoClassDefFoundError的错误出现

 三、SLF4J & Logback

  • SLF4J和 Logback 也是Gülcü 创立的项目,目的是为了提供更高性能的实现
  • SLF4J 采用比较熟悉的方式——接口和实现分离,有个纯粹的接口层——slf4j-api工程,这个里边基本完全定义了日志的接口,所以对于开发来说,只需要使用这个即可
  • logback完全实现了slf4j-api的接口,并且性能也比log4j更好,同时实现了变参占位符日志输出方式等等新特性
  • 对于用户来说只要使用SLF4J提供的接口,即可隐藏日志的具体实现,SLF4J提供的核心API是一些接口和一个LoggerFactory的工厂类,用户只需按照它提供的统一纪录日志接口,最终日志的格式、纪录级别、输出方式等可通过具体日志系统的配置来实现,因此可以灵活的切换日志系统

1.Logback是log4j的升级版,当前分为三个目标模块:

  • logback-core:核心模块,是其它两个模块的基础模块
  • logback-classic:是log4j的一个改良版本,同时完整实现 SLF4J API 使你可以很方便地更换成其它日记系统如log4j 或 JDK14 Logging
  • logback-access:访问模块 与 Servlet容器集成 提供 通过 Http 来访问日记的功能,是logback不可或缺的组成部分

2.Logback相较于log4j有更多的优点:

  • 更快的执行速度
  • 更充分的测试
  • logback-classic 非常自然的实现了SLF4J
  • 使用XML配置文件或者Groovy
  • 自动重新载入配置文件
  • 优雅地从I/O错误中恢复
  • 自动清除旧的日志归档文件
  • 自动压缩归档日志文件
  • 谨慎模式
  • Lilith
  • 配置文件中的条件处理
  • 更丰富的过滤

3.不同日志系统的桥接工程

  • 不同的日志框架(JCL、LOG4J、LOG4J2、JUL)都可以桥接到SLF4J,再通过 SLF4J 适配到到 Logback
  • 需要注意的是不能有循环的桥接,比如下面这些依赖就不能同时存在:
    • jcl-over-slf4j 和 slf4j-jcl
    • log4j-over-slf4j 和 slf4j-log4j12
    • jul-to-slf4j 和 slf4j-jdk14

四、从JavaBean讲到Spring

1.Java Bean

  • Java语言欠缺属性、事件、多重继承功能
  • 如果要在Java程序中实现一些面向对象编程的常见需求,只能手写大量胶水代码。Java Bean正是编写这套胶水代码的惯用模式或约定。这些约定包括getXxx、setXxx、isXxx、addXxxListener、XxxEvent等。遵守上述约定的类可以用于若干工具或库
  • javaBean就是实体类(一个可复用的类),用来封装对象,这个类里面全部都是属性值,和get,set方法
  • 为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器
  • Java bean必须保持向后兼容性

例:在Java标准库中,,绝对不会出现public int size这样的代码,而一定会一开始就写成:

private int size;

public int getSize( ){return size;}

        让用户一开始就使用getSize,以便有朝一日修改getSize实现时,不破坏向后兼容性。这种public int getSize() { return size; }的惯用手法,就是Java Bean。

2.JSP+Java Bean

  • 在jsp上,  可以用java bean 来封装业务逻辑,保存数据到数据库
    • jsp 直接用来接受用户的请求, 然后通过java bean 来处理业务, 具体的使用方法是:
      • HTTP request中的所有参数都设置到 user 这个java bean 对应的属性上去
      • 只要保证 http request中的参数名和 java bean 中的属性名是一样的
      • 这个模型叫做JSP Model 1, 因为他们的应用规模都很小, 用Model 1 使得开发很快速,所以受到了很多Java程序员的欢迎
      • 但在项目中频繁使用了Model 1 导致整个系统的崩溃,因为系统中有好几千个jsp, 这些jsp互相调用(通过GET/POST), 到了最后调用关系无人能搞懂
  • 为解决这个问题,又推出了 :JSP Model 2(MVC思想采用)
    • Servlet 充当Controller
    • jsp 充当 View
    • Java bean 就是Model
    • 业务逻辑, 页面显示, 和处理过程做了很好的分离

3.J2EE(Java EE):同Java Bean(Enterprise Java bean,EJB)一样,是一个规范

  • JDBC:  Java 数据库连接
  • JNDI :  Java 命名和目录接口, 通过一个名称就可以定位到一个数据源, 连jdbc连接都不用
  • RMI:  远程过程调用,  让一个机器上的java 对象可以调用另外一个机器上的java 对象 
  • JMS :   Java 消息服务,  可以使用消息队列了
  • JTA:  Java 事务管理, 支持分布式事务, 能在访问、更新多个数据库的时候,仍然保证事务, 还是分布式
  • Java mail : 收发邮件

Session bean罪状:代码的侵入性

4.Spring

  • Spring 框架顺应了POJO的潮流, 提供了一个spring 的容器来管理这些POJO, 也叫bean
  • 对于一个Bean 来说,如果你依赖别的Bean , 只需要声明即可, spring 容器负责把依赖的bean 给“注入进去,即“依赖注入”(DI)
  • 如果一个Bean 需要一些像事务,日志,安全这样的通用的服务, 也是只需要声明即可, spring 容器在运行时能够动态的“织入”这些服务, 这叫面向切面(AOP)

5.JavaBean 和 Spring中Bean的区别

JavaBean:

  • javaBean就是实体类(一个可复用的类),用来封装对象,这个类里面全部都是属性值,和get,set方法
  • 为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器

spring bean:

对于使用Spring框架的开发人员来说,我们主要做的主要有两件事情:

  • 开发Bean
  • 配置Bean

而Spring帮我们做的就是根据配置文件来创建Bean实例,并调用Bean实例的方法来完成“依赖注入”,可以把Spring容器理解成一个大型工厂,Bean就是该工厂的产品,工厂(Spirng容器)里能生产出来什么样的产品(Bean),完全取决于我们在配置文件中的配置。其实就是根据配置文件产生对象,而不需要人为的手动去创造对象,降低了耦合

  • 所有可以被spring容器实例化并管理的java类都可以称为bean
  • 用处不同:传统javabean更多地作为值传递参数,而spring中的bean用处几乎无处不在,任何组件都可以被称为bean
  • 写法不同:传统javabean作为值对象,要求每个属性都提供getter和setter方法;但spring中的bean只需为接受 设值注入 的 属性提供setter方法
  • 生命周期不同:传统javabean作为值对象传递,不接受任何容器管理其生命周期;spring中的bean有spring管理其生命周期行为

Java Bean写法:

public class A{
private String a;
private void setA(String a){
this.a = a;
}
private String getA(){
return a;
}
}

 spring bean写法:

  • id是给这个对象定的别名
  • class是这个实体类的全路径名
  • 根据配置文件来创建Bean实例,并调用Bean实例的方法 
  • bean里面还有很多属性
<bean id="p1" class="com.zking.Pojo.Person" scope="prototype">
//及时加载 加载你的xml配置文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
//getbean输入你配置类的别名得到 person对象
 Person p = (Person) applicationContext.getBean("p1");

猜你喜欢

转载自blog.csdn.net/weixin_45864705/article/details/128610561