目录
Spring的个人总结
懒加载,注解配置导入xml配置,bean的name的属性
上午主要在原有的xml配置文件中加入了懒加载
<bean id="lazyBean" class="com.lanou3g.spring.bean.LazyHeJinJie" lazy-init="true" init-method="init" />
懒加载,顾名思义,就是我们只有在getbean时,IOC容器才会给我们生成init方法和destroy方法,如果不在bean里面添加lazy-init=“true”,不管我们get不get这个bean,IOC都会生成init方法和destory方法,前提是bean里面声明init-method和destory-method实现类还要有这两个方法
bean的name方法
这里面name作用和id一样,只不过name可以有多个,而id只能有一个,通俗来讲id就像你的正名具有唯一性,而name就像你的别名,可以有多个,但是作用都是一样的,别人一喊反正都是你,你都会响应别人
这里面的id的值,如果只是xml配置不牵扯注解(注解就是在某个类添加@Component())id的值随意起,牵扯到注解,在某个类添加@Component(“kkk”)后就相当于在xml中配置了,不要在xml在配置这个类了
<bean id="student" name="stu,student1,sd1" class="com.lanou3g.spring.bean.Student">
<constructor-arg name="nickName" value="三哥" />
<constructor-arg name="sname" value="张三" />
<constructor-arg name="fruit" ref="banana" />
</bean>
// 获取applicationContext.xml中配置的name属性为:stu,student1,sd1
Student stu = ctx.getBean(“sd1”, Student.class);
System.out.println(stu.getNickName());
注解配置导入xml配置
其实我们可以通过xml和注解中的任意一种去获得对象,在我们刚开始学的时xml中设置注解方式
<context:component-scan base-package=“com.lanou3g.spring” />
在xml中设置这个context 就可以扫描com.lanou3g.spring下所有的包,看哪些包下的类是带有注解的
后面学的是注解配置导入xml配置,简单来说,在某个类(App.java)加一个@Configuration
用@Configuration注解的类就相当于是一个xml的配置文件,然后我们在这个类中导入xml配置文件//@ImportResource(“applicationContext.xml”)
AnnotationApplicationContext用于初始化ioc容器(注解方式配置文件(用@Configuration注解的类))
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(App.class);
这种是获得App这个class类中的对象和导入这个类中的xml中的bean对应的对象
ClassPathXmlApplicationContext用于初始化ioc容器(基于类路径下基于xml方式的配置)
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
这种是获得xml中的bean的对象,以及xml中的<context:component-scan base-package="com.lanou3g.spring" />扫描com.lanou3g.spring下的注解
两种方式各有优势
注入匿名内部bean
先在xml中配置
<bean id="stu1" class="com.lanou3g.spring.bean.Student">
<property name="fruit">
<bean class="com.lanou3g.spring.simple.Apple" />
</property>
</bean>
在方法中获得bean,进而调用
/**
* 通过标签注入一个匿名内部bean
*/
public void testInjectInnerBean(ApplicationContext ctx) {
Student stu = ctx.getBean(“stu1”, Student.class);
stu.getFruit().eatFruit();
}
注入集合型属性,注入null,空字符串类型属性值, 注入复合属性值
**<!-- 注入集合、Map类型参数 -->**
在xml中配置list,map
<bean id="saiSai" class="com.lanou3g.spring.bean.JinSaiSai">
<property name="hobbies">
<list>
<value>游泳</value>
<value type="java.lang.Integer">0034</value>
//type是要输出的类型,如type为Integer,那么输出就是34,如果是String ,输出的是0034
**//注入null** **//注入空字符串** //在jinsaisai类型中有一个yinsaisai类型的属性, <bean class="com.lanou3g.spring.bean.YinSaiSai" />
</property>
//yinsaisai类型的属性中又包含了一个age属性,并且age属性值需要设置为28
<property name="yinSaiSai.age" value="28" />
</bean>
/**
* 练习注入集合、Map类型…
* @param ctx
*/
在具体的方法中实现
public void testInjectListMap(ApplicationContext ctx) {
JinSaiSai saisai = ctx.getBean(JinSaiSai.class);
// 获取注入的list属性
List hobbies = saisai.getHobbies();
for(Object hobby : hobbies) {
System.out.println(“类型:” + hobby.getClass()+", 值:" + hobby);
}
// 获取注入的map属性
System.out.println(saisai.getGameTitles());
// 获取普通属性nickName
System.out.println("nickName: " + saisai.getNickName());
// 获取关联对象中的属性值
System.out.println("银赛赛中的age: " + saisai.getYinSaiSai().getAge());
}
注入外部properties文件的属性值
首先建一个文件放置配置文件的
jdbc.url=jdbc:mysql://localhost:3306/lanou?charsetEncoding=utf8
jdbc.driver=com.mysql.jdbc.Driver
jdbc.user=root
jdbc.password=root
<!-- 方式一 -->
<!--<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties" />
</bean>-->
<!-- 方式二 -->
<!-- 引入外部的properties文件结束 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
很显然方式二更方便点
<!-- 将外部properties文件中的属性注入到bean中 -->
<bean id="jdbcConf" class="com.lanou3g.spring.bean.JDBCConf">
<property name="url" value="${jdbc.url}" />
<property name="driver" value="${jdbc.driver}" />
<property name="userName" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
</bean>
然后在具体的方法中实现
/**
* 练习注入外部properties配置文件
* @param ctx
*/
public void testInjectProperties(ApplicationContext ctx) {
JDBCConf jdbcConf = ctx.getBean(JDBCConf.class);
System.out.println(jdbcConf.getUrl());
System.out.println(jdbcConf.getDriver());
System.out.println(jdbcConf.getUserName());
System.out.println(jdbcConf.getPassword());
}
通过p命名空间注入属性
就是把xml的头几行
//xmlns:context="http://www.springframework.org/schema/context"
//xmlns:context="http://www.springframework.org/schema/context"
改成
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
<!-- 通过p命名空间来注入属性 -->
<!--<bean id="yunjie1" class="com.lanou3g.spring.bean.YunJie">
<property name="sname" value="云姐" />
</bean>-->
<!-- 等效于上面的配置 -->
<bean id="yunjie1" class="com.lanou3g.spring.bean.YunJie" p:sname="云姐" />
<!-- 通过c命名空间来注入构造参数 -->
<!--<bean id="yunjie2" class="com.lanou3g.spring.bean.YunJie">
<constructor-arg name="sname" value="雲杰" />
</bean>-->
<!-- 等效于上面的配置 -->
<bean id="yunjie2" class="com.lanou3g.spring.bean.YunJie" c:sname="雲杰" />
/**
* 测试通过p和c命名空间注入属性和构造参数
*/
public void testInjectPAndC(ApplicationContext ctx) {
YunJie yunJie1 = ctx.getBean("yunjie1", YunJie.class);
System.out.println("yunjie1(通过p注入属性setter), sname: " + yunJie1.getSname());
YunJie yunJie2 = ctx.getBean("yunjie2", YunJie.class);
System.out.println("通过c注入构造参数, sname: " +yunJie2.getSname());
}
##构造方法注入
- 有参和无参
<beans>
<bean id="beanOne" class="x.y.ThingOne">
<!-- 通过此标签注入构造方法中的参数 -->
<constructor-arg name="age" value="18" />
<constructor-arg type="java.lang.String" value="张三" />
<constructor-arg ref="beanTwo"/>
</bean>
<!-- <constructor-arg name="age" value="18" />对应的是具体类的有参构造方法-->
<bean id="beanTwo" class="x.y.ThingTwo"/>
</beans>
- 通过c命名空间注入参数
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="beanTwo" class="x.y.ThingTwo"/>
<bean id="beanThree" class="x.y.ThingThree"/>
<!-- 传统方式注入构造参数 -->
<bean id="beanOne" class="x.y.ThingOne">
<constructor-arg name="thingTwo" ref="beanTwo"/>
<constructor-arg name="thingThree" ref="beanThree"/>
<constructor-arg name="email" value="something@somewhere.com"/>
</bean>
<!-- c命名空间方式注入构造参数 -->
<bean id="beanOne" class="x.y.ThingOne" c:thingTwo-ref="beanTwo"
c:thingThree-ref="beanThree" c:email="something@somewhere.com"/>
</beans>
##自动装配
- ByName
package com.lanou3g.spring.bean;
import lombok.Getter;
import lombok.Setter;
/**
* 自动装配属性
*/
@Getter
@Setter
public class AutoInjectByNameTeacher {
private String tname;
private Student student;
}
- ByType
package com.lanou3g.spring.bean;
import lombok.Getter;
import lombok.Setter;
/**
* 自动装配属性
*/
@Getter
@Setter
public class AutoInjectByTypeTeacher {
public AutoInjectByTypeTeacher() {}
public AutoInjectByTypeTeacher(LazyHeJinJie lazyHeJinJie) {
System.out.println("构造参数传入: " + lazyHeJinJie);
this.lazyStudent = lazyHeJinJie;
}
private String tname;
private LazyHeJinJie lazyStudent;
// 错误示范
// private Student student;
}
- ByConstructor
package com.lanou3g.spring.bean;
import lombok.Getter;
import lombok.Setter;
/**
* 自动装配属性
*/
@Getter
@Setter
public class AutoInjectByConstructorTeacher {
public AutoInjectByConstructorTeacher() {}
public AutoInjectByConstructorTeacher(LazyHeJinJie lazyHeJinJie) {
System.out.println("构造参数传入: " + lazyHeJinJie);
this.lazyStudent = lazyHeJinJie;
}
private String tname;
private LazyHeJinJie lazyStudent;
// 错误示范
// private Student student;
}
测试类实现
/**
* 练习自动注入
* @param ctx
*/
public void testAutoInject(ApplicationContext ctx) {
// 按照名称自动注入属性
/* AutoInjectByNameTeacher teacher = ctx.getBean("teacherByName" , AutoInjectByNameTeacher.class);
System.out.println("教师名称: " + teacher.getTname());
System.out.println("所教学生:" + teacher.getStudent().getSname());
*/
// 按照类型自动注入属性(容器中符合此类型的bean只能有一个,否则报错)
/* AutoInjectByTypeTeacher teacherByType = ctx.getBean("teacherByType" , AutoInjectByTypeTeacher.class);
System.out.println("教师名称(类型): " + teacherByType.getTname());
teacherByType.getLazyStudent().destroy();*/
// 下面这行示范了按照类型自动注入,但符合类型不唯一的情况(会直接报错)
// 解决方案就是换成按照名称自动注入
//System.out.println("学生姓名:" + teacherByType.getStudent().getSname());
// 构造器参数自动注入(按照类型)(容器中符合此类型的bean只能有一个,否则报错)
AutoInjectByConstructorTeacher teacherByConstructor = ctx.getBean("teacherByConstructor" , AutoInjectByConstructorTeacher.class);
System.out.println("教师名称(构造参数): " + teacherByConstructor.getTname());
teacherByConstructor.getLazyStudent().destroy();
}