目录
(2)配置文件的命名:没有硬性要求,建议我们:application.xml
问题:未来在开发过程中,是不是所有的对象,都会交给Spring工厂来创建?
回答:理论上是的,但是有特例:实体对象(entity)是不会交给Spring创建,它是由持久层框架进行创建。
1.Spring与日志框架进行整合,日志框架就可以在控制台中,输出Spring框架进行过程中地一些重要的信息。
2.好处:便于了解Spring框架的运行过程,利于程序的调试。
Spring.x默认整合的日志框架logback log4j2
2.Spring注入的原理分析(简易版)Spring通过底层调用对象属性对应的set方法,完成成员变量的赋值,这种方法我们也称之为
入门案例
1.环境搭建
-
Spring的jar包
<!--设置pom依赖-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
2.创建Spring配置文件
(1)配置文件的放置位置:任意位置没有硬性要求
(2)配置文件的命名:没有硬性要求,建议我们:application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
3.Spring的核心API
(1)ApplicationContext
<1>作用:Spring提供的ApplicationContext这个工厂,用于对象的创建
<2>好处:解耦合
(2)ApplicationContext接口类型
接口:屏蔽实现的差异
非外包环境:ClassPathXmlApplicationContext
web环境:XmlWebApplicationContext
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Spring</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.14.RELEASE</version>
</dependency>
</dependencies>
</project>
重量级资源
-
ApplicationContext工厂的对象占用大量内存
-
不会频繁的创建对象:一个应用只会创建一个工厂对象
-
ApplicationContext:一定是线程安全的(多线程并发访问)
4.程序开发
-
创建类型
-
配置文件的配置 applicationContext.xml
-
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--id属性 名字(唯一) class属性 配置全限定名--> <bean id = "person" class="com.baizhiedu.basic.Person"/> </beans>
-
通过工厂类,获得对象ApplicationContext
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
//当前Spring的配置文件中,只能有一个<bean class>是person类型
Person person = (Person) ctx.getBean("person");
System.out.println("person = "+person)
如果这里抛出一个异常,说明在applicationContext.xml文件中包含两个相同的class="com.baizhiedu.basic.Person,以至于该对象不知道调用哪一个?
xml文件如下图:
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
//当前Spring的配置文件中,只能有一个<bean class>是person类型
Person person = (Person) ctx.getBean("person");
System.out.println("person = "+person)
5.细节分析
名词解释
Spring工厂创建的对象,叫做Bean或者组件(componet)
Spring工厂的相关的方法
//通过这种方式获得对象,就不需要强制类型转换
Person person = ctx.getBean("person",Person.class);
System.out.println("person = "+person);
Person person = ctx.getBean(Person.class);/*Person.class中的class是来自于applicationContext.xml文件中的class="com.baizhiedu.basic.Person*/
System.out.println("person = "+person);
// 获取的是Spring工厂配置文件中所有bean标签的id值,person person1
String[] beanDefinitionNames = ctx.getBeanDefinitionNames();
for(String beanDefinitionName:beanDefinitionNames){
System.out.println("beanDefinitionName = " +beanDefinitionName);
}
*/
// 根据类型获得Spring配置文件中对应的id值
String[] beanNamesForType = ctx.getBeanNamesForType(Person.class);
for(String id:beanNamesForType){
System.out.println("id = "+id);
}*/
// 用于判断是否存在指定id值得bean----containsBeanDefinition
if (ctx.containsBeanDefinition("person2")) {
System.out.println("true = "+true);
}else{
System.out.println("false ="+false);
}*/
// 用于判断是否存在指id值得bean----containsBean
if (ctx.containsBean("person")) {
System.out.println("true = "+true);
}else{
System.out.println("false = "+false);
}
}
配置文件中需要注意得细节
1.只配置class属性
<bean class = "com.baizhiedu.basic.Person"/>
a)上述这种配置有没有id值com.baizhiedu.basic.Person
b)应用场景:如果这个bean只要使用一次,那么就可以省略id值
如果这个bean会使用多次,或者其他bean引用需要设置id值
2.name属性
作用:用于在Spring的配置文件中,为bean对象定义别名(小名)
相同:
-
1.ctx.getBean("id|name")|-->object <bean id ="" class = "" 等效于 <bean name = "" class = ""
区别:
-
别名可以定义多个,但是id属性只要有一个值
-
2.xml的id值属性的值,命名要求:必须以字母开头,字母 数字 下划线,连字符 不能以特殊字符开头 /person
name属性的值,命名没有要求
name属性会应用在特殊命名的场景下:/person
xml发展到今天:id属性的限制,不存在/person
6.Spring工厂的底层实现原理(简易版)
利用工厂创建对象从而去得到Person类里面地空参方法
@Test
public void test06(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
Person person = (Person) ctx.getBean("person");
System.out.println("p"+person);
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--id属性 名字(唯一)
class属性 配置全限定名-->
<!-- <bean id = "person" class="com.baizhiedu.basic.Person"/>-->
<!-- <bean id = "person1" class="com.baizhiedu.basic.Person"/>-->
<bean id="person" class = "com.baizhiedu.basic.Person"></bean>
</beans>
package com.baizhiedu.basic;
public class Person {
public Person(){
System.out.println("Person");
}
}
7.思考
问题:未来在开发过程中,是不是所有的对象,都会交给Spring工厂来创建?
回答:理论上是的,但是有特例:实体对象(entity)是不会交给Spring创建,它是由持久层框架进行创建。
Spring5.x与日志框架地整合
1.Spring与日志框架进行整合,日志框架就可以在控制台中,输出Spring框架进行过程中地一些重要的信息。
2.好处:便于了解Spring框架的运行过程,利于程序的调试。
SPring如何整合日志框架
默认
SPring1.2.3早期都是于commons-logging-jar
Spring.x默认整合的日志框架logback log4j2
SPring5.x整合log4j
-
1.引入log4j jar 包
-
2.引入log4.properties配置文件
pom
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
log4j.properties
log4j.rootLogger = debug,console
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}% - 5p%{1}:%L - %m%n
注入(Injecttion)
1.什么是注入?
-
通过Spring工厂及配置文件,为所创建对象得成员变量赋值
1.1为什么需要注入?
通过代码为成员变量赋值存在耦合
public void test07(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
Person person= (Person) ctx.getBean("Person");
person.setId(1);
/*通过代码为成员变量赋值存在耦合
* */
person.setName("k");
System.out.println("person"+person);
}
1.2如何进行注入【开发步骤】
-
类的成员变量提供set,get方法
-
配置spring文件的配置文件
<bean id="Person" class="com.baizhiedu.basic.Person"> <property name = "id"> <value>10</value> </property> <property name = "name"> <value>liar</value> </property> </bean> </beans>
1.3注入好处
-
解耦合
-
package com.baizhiedu.basic;
public class Person {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
<bean id="Person" class="com.baizhiedu.basic.Person"><!--此标签等效于new运算,将创建一个构造方法-->
<property name = "id">
<value>10</value>
</property>
<property name = "name">
<value>liar</value>
</property>
</bean>
</beans>
2.Spring注入的原理分析(简易版)
Spring通过底层调用对象属性对应的set方法,完成成员变量的赋值,这种方法我们也称之为set注入
Set注入详解
1.JDK内置基本类型
1.1string+8种基本类型
<value>suns</value>
1.2数组
<property name="emails">
<list>
<value>192@qq.com</value>
<value>164@qq.com</value>
<value>11@qq.com</value>
</list>
</property>
1.3 Set集合
set集合里面不一定只能写value,也可以写别的,因为set集合能存一切的对象。
<property name="tels">
<set>
<value>1381111</value>
<value>123131</value>
<value>342442</value>
<set></set>
<list></list>
</set>
</property>
1.4list集合
list集合里面的内容是允许重复的,也是有序的,里面也可以嵌套value,set,list等标签
<property name="address">
<list>
<value>nick</value>
<value>yang</value>
<value>hello</value>
<value>hello</value>
</list>
</property>
1.5Map集合
注意:map---entry---key有特定的标签<key></key>
值根据对应类型选择对应类型的标签
<property name="qqs">
<map>
<entry>
<key><value>suns</value></key><!--key标签使用value标签的原因是值为string类型-->
<value>2144324</value>
</entry>
<entry>
<key><value>sun</value></key><!--key标签使用value标签的原因是值为string类型-->
<value>2145344</value>
</entry>
</map>
</property>
1.6properties
properties 类型 特殊的MAP key = String value = String
<property name="p">
<props>
<prop key="key1">value1</prop>
<prop key="key2">value2</prop>
</props>
</property>
1.7复杂的JDK类型(DATE)
1.需要程序员自定义类型转换器,处理