Spring授课笔记1
1 MyBatis作业:自关联查询
- 以Emp为例完成功能
- 查询7839的所有直接下级员工(一对多)
- 查询员工scott及其上级的姓名、岗位(多对一)
- 使用分步查询和多表连接查询分别完成
提示:在Employee类中添加上级属性Employeemgr,添加下级属性List
外键关系是一种一对多的关联关系,自关联也不例外。而对于一对多关系进行讲解过:Customer和Order。但是之前是两张表,现在是一张表。要实现该功能,需要将Emp表当做两张表来对待:上级表、下级表。
2 准备工作
- 创建数据库表:
| CREATE TABLE DEPT(
DEPTNO INT(2) NOT NULL,
DNAME VARCHAR(14),
LOC VARCHAR(13)
);
ALTER TABLE DEPT
ADD CONSTRAINT PK_DEPT PRIMARY KEY (DEPTNO);
CREATE TABLE EMP
(
EMPNO INT(4) PRIMARY KEY,
ENAME VARCHAR(10),
JOB VARCHAR(9),
MGR INT(4),
HIREDATE DATE,
SAL DOUBLE(7,2),
COMM DOUBLE(7,2),
DEPTNO INT(2)
);
ALTER TABLE EMP
ADD CONSTRAINT FK_DEPTNO FOREIGN KEY (DEPTNO)
REFERENCES DEPT (DEPTNO);
COMMIT;
INSERT INTO DEPT (DEPTNO, DNAME, LOC)
VALUES (10, ‘ACCOUNTING’, ‘NEW YORK’);
INSERT INTO DEPT (DEPTNO, DNAME, LOC)
VALUES (20, ‘RESEARCH’, ‘DALLAS’);
INSERT INTO DEPT (DEPTNO, DNAME, LOC)
VALUES (30, ‘SALES’, ‘CHICAGO’);
INSERT INTO DEPT (DEPTNO, DNAME, LOC)
VALUES (40, ‘OPERATIONS’, ‘BOSTON’);
COMMIT;
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7369, ‘SMITH’, ‘CLERK’, 7902, ‘1980-12-17’, 800, NULL, 20);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7499, ‘ALLEN’, ‘SALESMAN’, 7698, ‘1981-02-20’, 1600, 300, 30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7521, ‘WARD’, ‘SALESMAN’, 7698, ‘1981-02-22’, 1250, 500, 30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7566, ‘JONES’, ‘MANAGER’, 7839, ‘1981-04-02’, 2975, NULL, 20);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7654, ‘MARTIN’, ‘SALESMAN’, 7698, ‘1981-09-28’, 1250, 1400, 30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7698, ‘BLAKE’, ‘MANAGER’, 7839, ‘1981-05-01’, 2850, NULL, 30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7782, ‘CLARK’, ‘MANAGER’, 7839, ‘1981-06-09’, 2450, NULL, 10);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7788, ‘SCOTT’, ‘ANALYST’, 7566, ‘1987-04-19’, 3000, NULL, 20);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7839, ‘KING’, ‘PRESIDENT’, NULL, ‘1981-11-17’, 5000, NULL, 10);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7844, ‘TURNER’, ‘SALESMAN’, 7698, ‘1981-09-08’, 1500, 0, 30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7876, ‘ADAMS’, ‘CLERK’, 7788, ‘1987-05-23’, 1100, NULL, 20);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7900, ‘JAMES’, ‘CLERK’, 7698, ‘1981-12-03’, 950, NULL, 30);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7902, ‘FORD’, ‘ANALYST’, 7566, ‘1981-12-03’, 3000, NULL, 20);
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES (7934, ‘MILLER’, ‘CLERK’, 7782, ‘1982-01-23’, 1300, NULL, 10);
COMMIT;
select * from emp | | —- |
- 创建Maven项目、添加MyBatis支持
创建实体类 | @Data
@AllArgsConstructor
@NoArgsConstructorpublic class Employee {
private Integer empno;
private String ename;
private String job;
private Integer mgr; // 只知道上级的员工编号 empno
private Double sal;
private Double comm;
private Integer deptno;//一个上级可以有多个下级
private ListempList = new ArrayList<>();
//一个下级只有一个上级
private Employee manager; //empno,ename,job,mgr…..} | | —- |
创建Mapper接口 | public interface EmployeeMapper {
/
查询一个员工及其上级信息(上级只有一个)
/
public **Employee findEmpWithMgr(String ename);/
查询一个员工及其所有的直接下级的信息(下级可能多个)
@param empno
* @return
*/
public **Employee findMgrWithEmps(Integer empno);
} | | —- |
- 创建映射文件
| <?xml version=”1.0” encoding=”UTF-8” ?><!DOCTYPE mapper
PUBLIC “-//mybatis.org//DTD Mapper 3.0//EN”
“http://mybatis.org/dtd/mybatis-3-mapper.dtd"_>_<mapper namespace=”com.atguigu.mapper.EmployeeMapper”>
</mapper> | | —- |
- 创建测试类
| public class TestRelational {
SqlSession sqlSession = null;
@Before
public void before() throws IOException {
//1.根据配置文件创建了SqlSessionFactory
InputStream is = Resources.getResourceAsStream(“mybatis-config.xml”);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//2.使用SqlSessionFactory创建了SqlSession
sqlSession = factory.openSession();//默认false
}
@After
public void after(){
//手动提交或者回滚事务
sqlSession.commit();
//关闭资源
sqlSession.close();
}
} | | —- |
3 查询7839的所有直接下级员工(多表连接查询方式)
public interface EmployeeMapper { / 查询一个员工及其所有的直接下级的信息(下级可能多个) @param empno * @return */ public **Employee findMgrWithEmps(Integer empno); } |
---|
<select id=”findMgrWithEmps” resultMap=”employeeMap”> select m.empno,m.ename,m.job,m.mgr,m.hiredate,m.sal,m.comm,m.deptno, e.empno empno1,e.ename ename1,e.job job1,e.mgr mgr1,e.hiredate hiredate2,e.sal sal3,e.comm comm3,e.deptno deptno3 from emp m — manager 上级 join emp e — employee 下级 on (e.mgr = m.empno) where m.empno = #{empno} </select> |
<resultMap id=”employeeMap” type=”com.atguigu.entity.Employee”>
<id column=”empno” property=”empno”></id>
<result column=”ename” property=”ename”></result>
<result column=”job” property=”job”></result>
<result column=”mgr” property=”mgr”></result>
<result column=”hiredate” property=”hiredate”></result>
<result column=”sal” property=”sal”></result>
<result column=”comm” property=”comm”></result>
<result column=”deptno” property=”deptno”></result>
<collection property=”empList” ofType=”com.atguigu.entity.Employee”>
<id column=”empno1” property=”empno”></id>
<result column=”ename1” property=”ename”></result>
<result column=”job1” property=”job”></result>
<result column=”mgr1” property=”mgr”></result>
<result column=”hiredate2” property=”hiredate”></result>
<result column=”sal3” property=”sal”></result>
<result column=”comm3” property=”comm”></result>
<result column=”deptno3” property=”deptno”></result>
</collection>
</resultMap> |
| @Testpublic void testFindMgrWithEmps(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee manager = mapper.findMgrWithEmps(7839);
System.out.println(“上级信息:”);
System.out.println(manager);
System.out.println(“所有的下级信息”);
List
empList.forEach((emp)-> System.out.println(emp));
} |
注意1:使用连接查询,即使column和property一致,id和result的映射也不要省略
<id column=”empno” property=”empno”></id>
<result column=”ename” property=”ename”></result>
注意2:因为上级和下级都是一张表,列名相同,在进行resultMap映射时,可以通过别名来区分。
4 查询员工scott及其上级的姓名、岗位(分步连接查询)
方法1:可以采用连接查询完成
方法2:使用分步查询+延迟加载完成
public interface EmployeeMapper { / 查询指定姓名的员工信息(单表查询,分步查询第一步) select from emp where ename =’SCOTT’ @param ename * @return */ public Employee findByName(String ename); / 查询指定员工的上级信息 select from emp where empno = 7566 @param empno * @return */ public Employee findMgrById(Integer empno); } |
---|
<select id=”findByName” resultMap=”employeeMap2”> select _ _from emp where ename =#{ename} </*select> |
<select id=”findMgrById” resultType=”com.atguigu.entity.Employee”>
select _ _from emp where empno = #{empno}
</*select>
<resultMap id=”employeeMap2” type=”com.atguigu.entity.Employee”>
<id column=”empno” property=”empno”></id>
<association property=”manager”
select=”com.atguigu.mapper.EmployeeMapper.findMgrById”
column=”mgr”></association>
</resultMap> |
| @Testpublic void testFindByName2(){
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee emp = mapper.findByName(“SCOTT”);
System.out.println(emp);
} |
| 注意:
1. 因为分步查询是由多个单表查询合并而成,所以在ResultMap中,如果column和property一致,映射可以省略。但是建议保留id映射。
1. 关键的关键,还是associate的配置
1. 经过测试,association的 fetchType属性的默认值是”lazy”
|
5 Spring简介
6 认识Spring
是一家公司,更是一种技术
罗德·约翰逊(Rod Johnson) Spring框架的创始人,同时也是SpringSource的联合创始人
经过一系列的眼花缭乱的商业并购,其中涉及SpringSource、EMC、VMWare、Pivotal等公司,最终花落Pivotal公司。
7 Spring关键点
- Spring可以说是Java世界最成功的框架。在企业级应用中,大部分的企业架构都基于Spring框架。
- Spring是开源的,这一点和MyBatis、SpringMVC、Struts2、Hibernate等一样。
- Spring的出现是因为Sun EJB的失败。EJB是重量级技术,功能强大,但配置繁杂,占用资源多,对EJB容器有依赖(侵入性),测试不方便,运行缓慢。而Spring是轻量级技术,保持技术强大的同时,克服了EJB的种种缺点。
- 2004 年 03 月,Spring 1.0 版发布。2017 年 09 月,Spring 5.0 发布,基于JDK8。
- Spring的成功来自理念,而不是技术。最核心的理念是IoC(控制反转)和AOP(面向切面编程)。基础是IoC,AOP的最典型应用当属数据库事务的处理。
- Spring不是为了取代现有技术,不重复的造轮子,而是提供更好的整合模板来整合这些技术,开发更简单。
- 特别强调Spring优点的非侵入性或者低侵入性。使用POJO开发,不需要继承Spring API,通过配置扩展POJO功能,通过依赖注入、AOP、面向接口编程等,降低耦合性。即使Java应用离开了Spring已经可以运行。
- Spring已经从Spring一个产品发展为一个家族,处理Spring之外,还有SpringMVC、Spring Security、SpringData、SpringBoot和SpringCloud等,但他们的基础都是Spring 的 IOC 和 AOP。 https://spring.io/projects
8 Spring优点
非侵入性
IoC
AOP
容器
组件化
一站式
声明式9 Spring五大模块
10 认识IoC
11 Ioc
IOC:Inversion of Control,翻译过来是反转控制。
12 Ioc容器
Servlet 容器(Tomcat)能够管理 Servlet、Filter、Listener 这样的组件的一生,所以它是一个复杂容器。
IOC 容器也是一个复杂容器。它们不仅要负责创建组件的对象、存储组件的对象,还要负责调用组件的方法让它们工作,最终在特定情况下销毁组件。
Spring 的 IOC 容器就是 IOC 思想的一个落地的产品实现。IOC 容器中管理的组件也叫做 bean。
Spring认为一切类都是Bean,比如实体类、DAO类、业务层、控制类、通知类等,容纳这些Bean的是Spring提供的IoC容器,所以Spring是一种基于Bean的编程
13 Ioc的API
①BeanFactory
这是 IOC 容器的基本实现,是 Spring 内部使用的接口。面向 Spring 本身,不提供给开发人员使用。
②ApplicationContext
BeanFactory 的子接口,提供了更多高级特性。面向 Spring 的使用者,几乎所有场合都使用 ApplicationContext 而不是底层的 BeanFactory。
以后在 Spring 环境下看到一个类或接口的名称中包含 ApplicationContext,那基本就可以断定,这个类或接口与 IOC 容器有关。
类型名 | 简介 |
---|---|
ClassPathXmlApplicationContext | 通过读取类路径下的 XML 格式的配置文件创建 IOC 容器对象 |
FileSystemXmlApplicationContext | 通过文件系统路径读取 XML 格式的配置文件创建 IOC 容器对象 |
ConfigurableApplicationContext | ApplicationContext 的子接口,包含一些扩展方法 refresh() 和 close() ,让 ApplicationContext 具有启动、关闭和刷新上下文的能力。 |
WebApplicationContext | 专门为 Web 应用准备,基于 Web 环境创建 IOC 容器对象,并将对象引入存入 ServletContext 域中。 |
14 Spring的第一个示例
15 定义接口和实现类
public interface HappyComponent { public void doWork(); } |
---|
public class HappyComponentImpl implements HappyComponent { public void doWork() { System.out.println(“HappyComponentImpl doWork()”); } } |
16 使用非Ioc方式操作
@Test public void testNoIoC(){ //创建对象 HappyComponent happyComponent = new HappyComponentImpl(); //调用方法 happyComponent.doWork(); //缺点1:需要亲自完成对象的创建过程,哪怕非常复杂 //缺点2:不利于修改,需要修改源代码} |
---|
17 添加依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.1</version> </dependency> |
---|
18 创建配置文件并定义Bean
配置文件名称任意,要放到resources目录下
<?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”> <bean id=”happyComponent” class=”com.atguigu.ioc.HappyComponentImpl”></bean> </beans> |
---|
19 使用IoC方式操作
@Testpublic void testWithIoC(){ //获取IoC容器 //BeanFactory factory = new ClassPathXmlApplicationContext(“classpath:spring.xml”); ApplicationContext factory = new ClassPathXmlApplicationContext(“classpath:spring.xml”); //从IoC容器中获取对象 //HappyComponent happyComponent = new HappyComponentImpl(); //HappyComponent happyComponent = (HappyComponent)factory.getBean(“happyComponent”); HappyComponent happyComponent = factory.getBean(“happyComponent”, HappyComponent.class); //调用方法 happyComponent.doWork(); //优点1:不需要亲自完成对象的创建过程,哪怕非常复杂 //缺点2:利于修改,需要修改源代码} |
---|
注意:MyBatis是替代JDBC访问数据库的、SpringMVC是封装了Servlet实现Web项目的,比较具体。Spring是比较抽象的,它的IoC和AOP关注与代码的优化,关注与解耦。
20 SpringIoc实验
21 获取Bean
方式1:按照Id获取Bean
Id必须唯一,否则:Bean name ‘happyComponent’ is already used in this
HappyComponent happyComponent = factory.getBean(“happyComponent”, HappyComponent.class); |
---|
方式2:按照Bean类名获取
前提:该类的实例只有一个,否则:expected single matching bean but found 2: happyComponent,happyComponent2
方式3:按照Bean类实现的接口名获取
可以。前提:该接口的实现类在配置文件中只有一个实例。
22 给bean的属性赋值:setter注入
| public class HappyComponentImpl implements HappyComponent {
private String componentName;
**public void **setComponentName(String componentName) {<br /> **this**.**componentName **= componentName;<br /> }
**public void **doWork() {<br /> System.**_out_**.println(**"HappyComponentImpl doWork():"**+**componentName**);<br /> }<br />} |
| —- |
| <bean id=”happyComponent2” class=”com.atguigu.ioc.HappyComponentImpl”>
<property name=”componentName” value=”zhangsan”></property>
</bean> |
| 底层使用反射技术。componentName====》setComponentName() |
23 给bean的属性赋值:引用外部已声明的bean
| public class HappyComponentImpl implements HappyComponent {
private String componentName; //和Integer等基本数据类型处理相同
private HappyMachine happyMachine; //引用类型
**public void **setComponentName(String componentName) {<br /> **this**.**componentName **= componentName;<br /> }
**public void **setHappyMachine(HappyMachine happyMachine) {<br /> **this**.**happyMachine **= happyMachine;<br /> }
**public void **doWork() {<br /> System.**_out_**.println(**"HappyComponentImpl doWork():"**+**componentName**+**","**+**happyMachine**);<br /> }<br />} |
| —- |
| <bean id=”happyMachine” class=”com.atguigu.ioc.HappyMachine”>
<property name=”machineName” value=”benz”></property>
</bean><bean id=”happyComponent3” class=”com.atguigu.ioc.HappyComponentImpl”>
<property name=”componentName” value=”lisi”></property>
<property name=”happyMachine” ref=”happyMachine”></property>
</bean> |
| 注意:
通过setter方法给基本类型和String类型的属性赋值,使用value
通过setter方法给引用类型的属性赋值,使用ref(reference 引用) |
24 给bean的属性赋值:内部bean
<bean id=”happyComponent4” class=”com.atguigu.ioc.HappyComponentImpl”> <property name=”componentName” value=”wangwu”></property> <property name=”happyMachine”> <bean id=”happyMachine2” class=”com.atguigu.ioc.HappyMachine”> <property name=”machineName” value=”BMW”></property> </bean> </property> </bean> |
---|
内部Bean的范围仅限于所在的标签,比如property 。 |
25 给bean的属性赋值:引入外部属性文件
体验和理解第三方Bean在Spring.xml 中的配置。
使用
<beans xmlns=”http://www.springframework.org/schema/beans“ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“ xmlns:context=”http://www.springframework.org/schema/context“ xmlns:cotext=”http://www.springframework.org/schema/context“ xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd** http://www.springframework.org/schema/context** https://www.springframework.org/schema/context/spring-context.xsd”> |
---|
jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/mybatis-examplejdbc.user=rootjdbc.password=root |
<cotext:property-placeholder location=”jdbc.properties”></cotext:property-placeholder> <bean id=”dataSource” class=”com.alibaba.druid.pool.DruidDataSource”> <property name=”driverClassName” value=”${jdbc.driver}”></property> <property name=”url” value=”${jdbc.url}”></property> <property name=”username” value=”${jdbc.user}”></property> <property name=”password” value=”${jdbc.password}”></property> </bean> |
@Testpublic void testDruidDataSource() throws SQLException { //获取IoC容器 ApplicationContext factory = new ClassPathXmlApplicationContext(“classpath:spring.xml”); //从IoC容器中获取对象 //1.按照Id获取Bean DataSource dataSource = factory.getBean(“dataSource”, DataSource.class); //调用方法 Connection connection = dataSource.getConnection(); System.out.println(connection); } |
26 给bean的属性赋值:级联属性赋值
<bean id=”happyMachine” class=”com.atguigu.ioc.HappyMachine”> <property name=”machineName” value=”benz”></property> </bean> <bean id=”happyComponent” class=”com.atguigu.ioc.HappyComponentImpl”> <property name=”componentName” value=”zhangsan”></property> <property name=”happyMachine” ref=”happyMachine”></property> <property name=”happyMachine.machineName” value=”BMW”></property> </bean> |
---|
注意:底层方法的调用:getHappyMachine().setMachineName(),比须提供这些方法
27 给bean的属性赋值:构造器注入
| <bean id=”happyMachine2” class=”com.atguigu.ioc.HappyMachine”>
<constructor-arg value=”Audi”></constructor-arg>
</bean>
<bean id=”happyComponent2” class=”com.atguigu.ioc.HappyComponentImpl”>
<constructor-arg value=”lisi”></constructor-arg>
<constructor-arg ref=”happyMachine2”></constructor-arg>
</bean>
<bean id=”happyComponent3” class=”com.atguigu.ioc.HappyComponentImpl”>
<constructor-arg ref=”happyMachine2” index=”1”></constructor-arg>
<constructor-arg value=”lisi” index=”0”></constructor-arg>
</bean> |
| —- |
28 给bean的属性赋值:特殊值处理
public class PropValue { private String commonValue; //null private String expression;// 5 < 6 private String expression2; } |
---|
<bean id=”propValue” class=”com.atguigu.ioc.PropValue”> <property name=”commonValue” > <null/> </property> <property name=”expression” value=”a < b”></property> <property name=”expression2” > <value><![CDATA[ a1 < b1]]></value> </property> </bean> |
29 给bean的属性赋值:使用p名称空间
xmlns:p=”http://www.springframework.org/schema/p“ |
---|
<bean id=”happyMachine3” class=”com.atguigu.ioc.HappyMachine” p:machineName=”BYD”> </bean> |
30 给bean的属性赋值:集合属性
集合类型:Array、List、Set、Map、Properties;
public class Student { private double [] scoreArr; //不需要分配空间 private List private Set private Map countriesMap = new HashMap private Properties properties; } |
---|
<bean id=”student” class=”com.atguigu.ioc.Student”> <property name=”scoreArr”> <array> <value>90</value> <value>100</value> <value>95</value> </array> </property> <property name=”courseList”> <list> <ref bean=”course1”></ref> <ref bean=”course2”></ref> <bean class=”com.atguigu.ioc.Course”> <property name=”cno” value=”3”></property> <property name=”cname” value=”SSM”></property> </bean> </list> </property> <property name=”friendSet”> <set> <value>马云</value> <value>化腾</value> <value>彦宏</value> </set> </property> <property name=”countriesMap”> <map> <entry key=”cn” value=”China”></entry> <entry key=”usa” value=”the United States of America”></entry> <entry key=”jp” value=”Japan”></entry> </map> </property> <property name=”properties”> <props> <prop key=”driverClassName”>com.mysql.jdbc.Driver</prop> <prop key=”user”>root</prop> <prop key=”pwd”>root</prop> </props> </property> </bean> |
<bean id=”course1” class=”com.atguigu.ioc.Course”>
<property name=”cno” value=”1”></property>
<property name=”cname” value=”Java”></property>
</bean>
<bean id=”course2” class=”com.atguigu.ioc.Course”>
<property name=”cno” value=”2”></property>
<property name=”cname” value=”MySQL”></property>
</bean> |
31 集合类型的bean
<?xml version=”1.0” encoding=”UTF-8”?><beans xmlns=”http://www.springframework.org/schema/beans“ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“ xmlns:context=”http://www.springframework.org/schema/context“ xmlns:cotext=”http://www.springframework.org/schema/context“ xmlns:p=”http://www.springframework.org/schema/p“ xmlns:util=”http://www.springframework.org/schema/util“ xsi:schemaLocation=”http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd** http://www.springframework.org/schema/context** https://www.springframework.org/schema/context/spring-context.xsd** http://www.springframework.org/schema/util** https://www.springframework.org/schema/util/spring-util.xsd”> |
---|
<util:list id=”courses”> <bean class=”com.atguigu.ioc.Course”> <property name=”cno” value=”10”></property> <property name=”cname” value=”JavaSE”></property> </bean> <bean class=”com.atguigu.ioc.Course”> <property name=”cno” value=”20”></property> <property name=”cname” value=”JavaEE”></property> </bean> <bean class=”com.atguigu.ioc.Course”> <property name=”cno” value=”30”></property> <property name=”cname” value=”SSM”></property> </bean> </util:list> |
@Testpublic void testContainerBean(){ //创建IoC容器 ApplicationContext context = new ClassPathXmlApplicationContext(“classpath:spring2.xml”); //从IoC容器获取Bean List //调用方法 courseList.forEach(c-> System.out.println(c)); } |
32 FactoryBean机制
- FactoryBean是Spring提供的一种整合第三方框架常用机制(后面SSM整合就好遇到它)。
- 和普通的bean不同,配置一个FactoryBean类型的bean,在获取bean的时候得到的并不是class属性中配置的这个类的对象,而是getObject()方法的返回值。
- 通过这种机制,Spring可以帮我们把复杂组件创建的详细过程和繁琐细节都屏蔽起来,只把最简洁的使用界面展示给我们。
33 bean的作用域
<bean id=”course1” class=”com.atguigu.ioc.Course” scope=”prototype”> <property name=”cno” value=”1”></property> <property name=”cname” value=”Java”></property> </bean> |
---|
@Test public void testScope(){ //创建IoC容器 ApplicationContext context = new ClassPathXmlApplicationContext(“classpath:spring3.xml”); System.out.println(“———-IoC容器已经创建———-“); //从IoC容器获取Bean Course course1 = context.getBean(“course1”, Course.class); Course course2 = context.getBean(“course1”, Course.class);// //调用方法 System.out.println(course1.hashCode()); System.out.println(course2.hashCode()); System.out.println(course1.equals(course2)); System.out.println(course1 == course2); |
} |