一、Spring5.x与日志框架的集成1.1为什么要集成?通过集成,您可以在控制台中输入Spring框架在运行过程中的一些重要信息,如bean对象的创建或销毁等。好处:便于理解Spring框架的运行过程,方便程序调试。1.2如何整合?默认情况下,spring框架自带的集成日志框架如下|Spring1、2、3早期都集成了commons-logging.jar|spring5.x默认集成日志框架logbacklogj2但这里我们打破默认,使用log4j日志框架1.导入log4jjar包2.导入log4j.properties配置文件pom依赖org.slf4jslf4j-log4j121.7.25log4jlog4j1.2.17log4j.properties#resources文件夹根目录###配置根目录log4j.rootLogger=debug.console###日志输出到控制台显示配置.appender.console.layout.ConversionPattern=%d{yyyy-MM-ddHH:mm:ss}%-5p%c{1}:%L-%m%n观察打印的log(运行junit测试后)23:29:05.482[main]DEBUGorg.springframework.context.support.ClassPathXmlApplicationContext-刷新org.springframework.context.support.ClassPathXmlApplicationContext@7bd4937b23:29:05.849[main]DEBUGorg.springfinframework.beans.factory-加载1个bean定义来自类路径资源[applicationContext.xml]23:29:05.905[main]DEBUGorg.springframework.beans.factory.support.DefaultListableBeanFactory-创建单例bean'u'u=cn.paul的共享实例。spring.demo.hellospring.entity.User@22356acd说明:从上面的配置文件我们看到它加载了实现类,然后读取对应的配置文件信息,最后创建了一个实例2.Injection接下来我们进入了最Spring,注入的好地方。2.1什么是注入?通过Spring工厂和配置文件,为创建的成员变量赋值(注意是成员变量)2.2为什么需要注入?上面我们通过工厂获取了对应的bean对象,但是如果我们要设置它对应的成员变量,那么我们还需要进一步调用它的set()方法,这样set的内容才会写到程序中在代码层面,其实也是有耦合的,所以和开始解决创建对象的耦合一样,我们通过编写配置文件和编码来给对象的成员变量赋值。下面是赋值成员变量的耦合代码。2.3如何注入(具体开发步骤)第一步:因为Spring工厂的本质是使用反射创建对象(底层调用set方法),所以创建的类必须提供setget方法第二步:配置Spring配置文件第三步:调用print方法查看结果2.4Spring注入原理分析(简易版)Spring通过调用对象属性的set方法完成对成员变量的赋值底层。这个方法叫做“”设置注入”3.注入细节如上面的配置文件所示,如果是String类型,我可以直接定义一个value属性,那么对于其他数据类型,是否需要更改呢?在这一段注入细节,我们主要讲解对于不同类型的成员变量,在标签中,需要嵌套其他标签xxxx下图列出了Spring可能涉及到的不同类型的成员变量注入3.1JDK内置类型3.1.1String+8种基本类型对于String+8个基本类型的成员变量,可以使用上面的形式注入变量注:通过在里面嵌入value<属性>标签属性只能是这几个String+8个基本类型的属性。3.1.2数组我们定义了一个私有字符串[]名字的数组;在User类中,在class="cn.paul.spring.demo.hellospring.entity.User"下方注入paulPaulLilyJhon
我们看到第一步是定义标签,然后定义标签,并注入值(可以多个,毕竟是数组)3.1.3集合集合首先要知道集合集合的特点是“无序的”andunique”,所以无论我们在set集合中定义什么形式,有多少个相同的值,最后打印出来的值都只有一个,而且打印的顺序很可能是乱序的(虽然你在正序,但还是要信任权威)我们在User类中定义了一个额外的privateSettels;set集合,下面注入其中114110110110112hihellogood
我们需要付出的注意的是,因为我们没有明确声明set集合中应该包含什么类型的变量,所以可以是任何类型。从集合中嵌入的标签,我们可以看到里面嵌入了标签和甚至[标签注意事项:记住不是所有嵌套的标签,只是一个String+8数据类型的标签3.1.4List集合首先,List集合的特点是:有序、可伸缩其次,在Spring中,其标签的定义与数组相同,都是],下面是对应的例子>
注意:记住不是所有的都是嵌套的标签,只是String+8数据类型的标签。3.1.5Map集合首先,Map集合是由entry键值对组成的类。必须有对应的映射,下面是privateMapqqs注意:key对应的类型是String类型,所以嵌套在标签里面它是标签;而键值对对应的value的类型是String类型,所以对应的标签也是标签。当然以后value的类型可能不是String类型,所以这个需要根据不同的数据。类型定义不同的标签(如[//]标签)总结:map-->-->key有特定的标签value是根据选择的对应类型对应标签3.1.6Properties类型首先,我们知道Properties类型是一个特殊的Map集合,它的键值对由组成。根据上面String类型使用的标签,我们知道它的用法应该是标签,但是由于它的组成已经硬编码在String类型中,所以所有的Spring都直接使用它自定义的简化版标签,如下value1value2备注:每个相当于上面Map集合的,然后是key属性映射对应key的名称,直接在标签中写入对应的值。4、用户自定义类型除了jdk定义的类,显然我们还有自定义的类,比如服务接口实现类定义的成员变量,xxxDao;4.1首先有两种声明方式第一步:为成员变量提供setter和getter方法第二步:在配置文件中定义如下备注:在tag内部name属性声明了其接口实现类中定义的成员变量4.2第一种赋值方式存在的问题1>配置文件冗余eg:如果一个接口的实现类定义了这个dao对象,那么我的其他类也如是dao对象定义好了,那我就需要多次定义tag,写重复的配置代码。实际例子:UserService的实现类定义了UserDao类OrderService的实现类定义了UserDao类2>注入的对象(UserDao)被创建了很多次,浪费了JVM内存资源,慢慢导致了Spring的单例问题。解决方法:(ref标签的使用)1>在代码层面,照常声明类,提供成员变量setter和getter方法2>在配置文件中,ref标签类实现解耦和单例备注:在Spring4.X中被废除,等价上面的方法也可以简写成下面这样,就是在标签里面嵌入ref属性:5.基于p命名空间简化5.1JDK类型注入注:我们用P:来代替标签,然后稍后直接定义名称和值。5.2用户自定义类型>首先我们定义一个bean>然后根据命名空间p简化为injecttherefobject6.构造注入Injection是集合注入之前通过Spring配置文件给成员变量赋值。Spring调用set方法,通过配置文件给成员变量赋值。注入就是通过Spring调用构造方法给成员变量赋值。方法(既然是构造注入,就必须有构造方法)publicclassPalyerimplementsSerializable{privateStringname;私人货币;publicPalyer(Stringname,intmoney){this.name=name;this.money=金钱;}@OverridepublicStringtoString(){return"Palyer{"+"name='"+name+'\''+",money="+money+'}';}}使用标签实现属性注入注意:上面的value属性只能对应的是String+8个基本类型,如果涉及到其他数据类型,那么使用上面的嵌入标签即可,上面的配置也可以这样写每天186.2构造方法重载首先我们知道重载是指:方法名相同,但参数个数、参数类型、参数顺序不同(只要其中一个条件6.2.1参数个数不同的情况假设现在我们重载了一个构造函数,如下:this.name=name;this.money=money;}publicPalyer(Stringname){this.name=name;}@OverridepublicStringtoString(){return"Palyer{"+"name='"+name+'\''+",money="+money+'}';}}=====================================我们通过控制构造函数的数量来控制调用哪个构造函数在配置文件中,如下paul======================================然后会调用入参为Stringname的构造方法,并创建一个对象6.2.2构造参数个数相同的情况假设现在我有多个入参个数的构造方法,那么此时,不能通过控制的个数来进行构造注入。我们需要在标签中指定类型属性。我的课程是以下公共课程PalyerimplementsSerializable{privateintmoney;私有字符串名称;publicPalyer(Stringname,intmoney){this.name=name;this.money=金钱;}publicPalyer(Stringname){this.name=name;}publicPayer(intmoney){this.money=money;}@OverridepublicStringtoString(){return"Palyer{"+"name='"+name+'\''+",money="+money+'}';}}========================================我配置配置文件如下(类型属性指定int类型)15七、注入总结不管是set注入还是construction注入,本质都是通过配置文件给成员变量赋值的一种实现方法问题:以后set注入还是construction注入应该在实战中使用?答:set注入会用的多一点,因为:1.构造注入有重载,相对麻烦2.Spring框架底层大量使用set注入