SSM框架(Spring + SpringMVC + MyBatis)学习笔记,第一课:Spring IoC

  1. Spring框架概述图
    这张图展示了,搭建项目时所需要的模块(对应的jar包),例如:使用spring框架连接数据库,则需要用到Core, Aop, Dao模块的jar包。
    Spring框架概述

  2. 下载使用eclipse搭建ssm框架(Spring + SpringMVC + MyBatis)所需要的jar包。这个jar包只能支持1.7及以下版本的JDK,若使用了高版本的JDK,需要去spring官网去下载jar包

    解压之后获得
    在这里插入图片描述
    本章主要介绍SpringIoC,所以只使用其中的ioc文件夹下的jar包和applicationContext.xml文件
    在这里插入图片描述
    在这里插入图片描述

  3. 创建web project
    打开eclipse,选择File >>> New >>> Dynamic Web Project
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    填写完项目名称之后,直接点击Finish,项目就创建完成了。
    创建之后的目录结构如下:
    在这里插入图片描述

  4. 打开下载的jar包,将ioc文件夹下的jar包复制到lib目录下,将applicationContext.xml文件复制到src目录下
    在这里插入图片描述
    到此,环境已经准备完成。

  5. 使用SpringIoC创建对象的三种方法
    src目录下创建一个class文件,用于接下来的测试
    在这里插入图片描述
    第一种方法:采用new构造器创建对象
    不使用框架

package org.springioc.test;

import java.util.Calendar;
import java.util.GregorianCalendar;

public class TestBean {

	public static void main(String[] args) {
		Calendar c1 = new GregorianCalendar();
		System.out.println("c1="+c1);

	}
	
}

使用框架
首先在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"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"  
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
		http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
		http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">

<!-- 使用new构造器方法创建对象 -->
<bean id="c2" class="java.util.GregorianCalendar"></bean>

</beans>

然后在测试类TestBean中通过框架创建对象

package org.springioc.test;

import java.util.Calendar;
import java.util.GregorianCalendar;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestBean {

	public static void main(String[] args) {
		Calendar c1 = new GregorianCalendar();
		System.out.println("c1="+c1);
		
		String conf = "applicationContext.xml";//配置文件的文件名
		//实例化容器
		ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
		//创建对象,
		//ac.getBean("c2", Calendar.class)
		//c2为配置文件applicationContext.xml中的id
		//Calendar.class为获取对象的类型
		Calendar c2222 = ac.getBean("c2", Calendar.class);
		System.out.println("c2222="+c2222);

	}
	
}

第二种方法:采用静态工厂方法创建对象
不使用框架
测试类TestBean

Calendar c3 = Calendar.getInstance();

使用框架
首先在applicationContext.xml中增加配置

<!-- 使用静态工厂方法创建对象 -->
<bean id="c3" class="java.util.Calendar" factory-method="getInstance"></bean>

测试类TestBean

Calendar c3333 = ac.getBean("c3", Calendar.class);
System.out.println("c3333="+c3333);

第三中方法:采用对象工厂方法创建对象
不使用框架
测试类TestBean

Date date = c3.getTime();
System.out.println("date="+date);

使用框架
首先在applicationContext.xml中增加配置,c3为第二种方法种配置的id

<!-- 采用对象工厂方法创建对象 -->
<bean id="date" factory-bean="c3" factory-method="getTime"></bean>

测试类TestBean

Date date3333 = ac.getBean("date", Date.class);
System.out.println("date3333="+date3333);
  1. 创建对象时单例,非单例控制
    使用以上方式创建对象,默认是单例(singleton),但是可以通过scope属性 更改,它的值有singleton(单例)和prototype(非单例)。
    下面举例说明:
    src目录下新建目录org.spingioc.bean,在此目录下新建类ExampleBean
package org.springioc.bean;

public class ExampleBean {

	public void execute() {
		System.out.println("调用execute方法");
	}

}

使用框架,创建对象
首先配置applicationContext.xml

<bean id="e1" class="org.springioc.bean.ExampleBean"></bean>

编写测试类ExampleTest

package org.springioc.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springioc.bean.ExampleBean;

public class ExampleTest {

	public static void main(String[] args) {
		String conf ="applicationContext.xml";
		ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
		ExampleBean e1 = ac.getBean("e1", ExampleBean.class);
		ExampleBean e2 = ac.getBean("e1", ExampleBean.class);
		System.out.println(e1==e2);
	}

}

结果为true,代表为singleton模式。
applicationContext.xml增加scope属性,将它改为非单例模式

<bean scope="prototype" id="e1" class="org.springioc.bean.ExampleBean"></bean>

再次运行测试类ExampleTest,结果为false,代表为非单例模式。

  1. 创建对象时初始化动作
    不使用框架,可以使用构造器构造代码块实现对象的初始化
package org.springioc.bean;

public class ExampleBean {
	
	{
		System.out.println("构造代码块!");
	}
	
	public ExampleBean() {
		System.out.println("无参构造函数!");
	}
	
	public void execute() {
		System.out.println("调用execute方法");
	}

}

运行测试类ExampleTest,控制台显示
在这里插入图片描述
使用框架
首先在ExampleBean类中增加初始化函数init

	public void init() {
		System.out.println("初始化方法!");
	}

init函数配置在applicationContext.xml

<bean init-method="init" scope="prototype" id="e1" class="org.springioc.bean.ExampleBean"></bean>

运行测试类ExampleTest,控制台显示
在这里插入图片描述
以上这两种方法初始化对象的区别,使用构造代码块构造器初始化对象,是在对象创建的过程中初始化对象,使用init-method初始化对象,是在对象创建完成再对对象做初始化动作。

  1. 对象的销毁
    applicationContext.xml中配置destroy-method实现对象的销毁。使用bean中的这个属性,需要两个条件支持
    第一个:必须实现AbstractApplicationContext容器,并且运行它的close方法
package org.springioc.test;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ExampleTest {

	public static void main(String[] args) {
		String conf ="applicationContext.xml";
		AbstractApplicationContext ac = new ClassPathXmlApplicationContext(conf);
		ac.close();
	}
}

第二个:对象必须是单例模式(singleton

<bean destroy-method="destroy"  init-method="init" scope="singleton" id="e1" class="org.springioc.bean.ExampleBean"></bean>

另外在ExampelBean中增加destroy方法

public void destroy() {
		System.out.println("销毁对象!");
	}

运行ExampleTest类,
在这里插入图片描述

  1. 控制单例对象的创建时机
    若需在实例化容器的时候创建对象,需要在applicationContext.xml配置三个属性
    第一个:abstract=“false”,不配置默认为false
    第二个:scope=“singleton” ,不配默认为singleton
    第三个:lazy-init="false"
<bean abstract="false" lazy-init="false" destroy-method="destroy" init-method="init" scope="singleton" id="e1" class="org.springioc.bean.ExampleBean"></bean>

否则在调用容器的getBean函数的时候创建对象

<bean abstract="false" lazy-init="true" destroy-method="destroy" init-method="init" scope="singleton" id="e1" class="org.springioc.bean.ExampleBean"></bean>
  1. applicationContext.xmlbean元素中配置的init-method, destroy-method, lazy-init是针对单个对象的;也可以在beans元素中配置default-init-method, default-destroy-method, default-lazy-init,这样对配置文件中的每一个对象都能生效。(了解)

  2. SpringIoC依赖注入(控制反转或反向控制)
    控制反转:改变了获取对象的方式,不使用框架的情况下,使用new创建对象;ioc中,由容器创建对象,对象的参数,以及对象之间的关系,只需要修改配置即可改变。
    下面介绍两种方式:
    第一种,构造器注入,这种方法需要创建有参的构造器
    首先创建一个Phone

package org.springioc.bean;

public class Phone {
	private String brand;
	private String price;
	
	public Phone(String brand, String price) {
		this.brand=brand;
		this.price=price;
	}
	
	public void show() {
		System.out.println("--手机--brand:"+brand+" price:"+price);
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public void setPrice(String price) {
		this.price = price;
	}
	
}

配置applicationContext.xml文件

<bean id="p1" class="org.springioc.bean.Phone">
	<!-- 构造器注入,index参数序号从零开始计数,value想要赋给对象属性的值 -->
	<constructor-arg index="0" value="苹果"></constructor-arg>
	<constructor-arg index="1" value="12000"></constructor-arg>
</bean>

编写测试类PhoneTest

package org.springioc.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springioc.bean.Phone;

public class PhoneTest {

	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		Phone p = ac.getBean("p1", Phone.class);
		p.show();
	}
	
}

第二种:set注入
创建Computer

package org.springioc.bean;

public class Computer {
	private String brand;
	private String price;
	
	public void show() {
		System.out.println("--电脑--brand:"+brand+" price:"+price);
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public void setPrice(String price) {
		this.price = price;
	}
	
}

配置applicationContext.xml文件

<bean id="pc" class="org.springioc.bean.Computer">
	<!-- set注入,name对象属性,value属性值 -->
	<property name="brand" value="联想"></property>
	<property name="price" value="8000"></property>
</bean>

编写测试类PhoneTest

package org.springioc.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springioc.bean.Phone;

public class PhoneTest {

	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		Phone p = ac.getBean("p1", Phone.class);
		p.show();
	}
	
}

另一种情况如果属性值为一个对象,该如何用注入的方式
创建Student

package org.springioc.bean;

public class Student {
	private Phone phone;
	private Computer pc;
	
	public void show() {
		phone.show();
		pc.show();
	}

	public void setPhone(Phone phone) {
		this.phone = phone;
	}

	public void setPc(Computer pc) {
		this.pc = pc;
	}
	
}

配置applicationContext.xml文件,使用ref引用原有的对象

<bean id="st" class="org.springioc.bean.Student">
	<property name="phone" ref="p1"></property>
	<property name="pc" ref="pc"></property>
</bean>

编写测试类StudentTest

package org.springioc.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springioc.bean.Student;

public class StudentTest {

	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		Student st = ac.getBean("st", Student.class);
		st.show();
	}

}
  1. 自动注入(autowrite),了解就可!
    Spring IoC容器可以自动装配(autowire)相互协作bean之间的关联关系。因此,如果可能的话,可以自动让Spring通过检查BeanFactory中的内容,来替我们指定bean的协作者(其他被依赖的bean)。autowire一共有五种类型(“no”, “byName”, “byType”, “constructor”, “autodetect”)。由于autowire可以针对单个bean进行设置,因此可以让有些bean使用autowire,有些bean不采用。autowire的方便之处在减少或者消除属性或构造器参数的设置,这样可以给我们的配置文件减减肥!
    下面以"byType"举例:
    配置applicationContext.xml文件
<bean id="st1" class="org.springioc.bean.Student" autowire="byType"></bean>

修改测试类StudentTest

package org.springioc.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springioc.bean.Student;

public class StudentTest {

	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		Student st = ac.getBean("st1", Student.class);
		st.show();
	}
}
  1. 各种类型的信息注入配置
    创建类MessageBean
package org.springioc.bean;

import java.sql.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Map.Entry;

public class MessageBean {
	private String name;
	private int age;
	private Date birth;
	private List<String> friends;
	private Set<String> cities;
	private Map<String,String> books;
	private Properties db;
	
	public void show() {
		String lstFriends="";
		for(int i=0;i<friends.size();i++) {
			lstFriends +=friends.get(i)+",";
		}
		System.out.println("name:"+name+", age:"+age+", birth:"+birth+", friends:"+lstFriends);
		
		for(String s : cities) {
			System.out.println(s);
		}
		
		Set<Entry<String,String>> booksSet = books.entrySet();
		for(Entry<String,String> e :booksSet) {
			System.out.println("key:"+e.getKey()+", value:"+e.getValue());
		}
		
		Set<Object> dbSet = db.keySet();
		for(Object key : dbSet) {
			System.out.println("key:"+key+", value:"+db.getProperty(key.toString()));
		}
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public void setBirth(String birth) {
		Date date =Date.valueOf(birth);
		this.birth = date;
	}

	public void setFriends(List<String> friends) {
		this.friends = friends;
	}

	public void setCities(Set<String> cities) {
		this.cities = cities;
	}

	public void setBooks(Map<String, String> books) {
		this.books = books;
	}

	public void setDb(Properties db) {
		this.db = db;
	}
	
}

第一,基础类型,和String类型

	<!-- 给name赋值null -->
	<property name="name">
		<null/>
	</property>
	<property name="age" value="18"></property>
	<!-- birth为Date类型,set方法需要重写 -->
	<property name="birth" value="2019-01-01"></property>

第二,List类型

	<property name="friends">
		<list>
			<value>朋友1</value>
			<value>朋友2</value>
		</list>
	</property>

第三,Set类型

	<property name="cities">
		<set>
			<value>城市1</value>
			<value>城市2</value>
		</set>
	</property>

第四,Map类型

	<property name="books">
		<map>
			<entry key="001" value="书1"></entry>
			<entry key="002" value="书2"></entry>
		</map>
	</property>

第五,Properties类型

	<property name="db">
		<props>
			<prop key="username">root</prop>
			<prop key="password">123456</prop>
		</props>
	</property>

编写测试类MessageTest

package org.springioc.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springioc.bean.MessageBean;

public class MessageTest {

	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		MessageBean msg = ac.getBean("msg", MessageBean.class);
		msg.show();
	}
}

第六,传递bean对象

<util:list id="fds">
	<value>朋友3</value>
	<value>朋友4</value>
</util:list>

<util:set id="cts">
	<value>城市3</value>
	<value>城市4</value>
</util:set>

<util:map id="boks">
	<entry key="003" value="书3"></entry>
	<entry key="004" value="书4"></entry>
</util:map>

<util:properties id="dbs">
	<prop key="user">root</prop>
	<prop key="password">123456</prop>
</util:properties>

<bean id="msg1" class="org.springioc.bean.MessageBean">
	<property name="friends" ref="fds"></property>
	<property name="cities" ref="cts"></property>
	<property name="books" ref="boks"></property>
	<property name="db" ref="dbs"></property>
</bean>

第七,Spring表达式注入

<bean id="msg1" class="org.springioc.bean.MessageBean">
	<property name="friends" ref="fds"></property>
	<property name="cities" ref="cts"></property>
	<property name="books" ref="boks"></property>
	<property name="db" ref="dbs"></property>
	<!-- 表达式注入 -->
	<property name="name" value="#{fds[0]}"></property>
	<property name="age" value="#{dbs.password}"></property>
</bean>

第八,读取properties文件
在src目录下创建db.properties文件,文件内容格式为key=value:

user=xiaohong
password=321123

配置applicationContext.xml文件,classpath代表src目录下

<util:properties id="dbParams" location="classpath:db.properties"/>
  1. 组件自动扫描
    组件自动扫描,可以按指定的包路径,将包下所有组件扫描,如果发现类定义前有以下标记,会将组件扫描到Sping容器
    @Component//其他组件
    @Controller//控制层组件
    @Service//业务层组件 xxxService
    @Repository//数据访问层组件 xxxDao
    @Named(需要引入第三方jar包,一般用不到!)

@Scope控制对象是否单例,默认单例
@PostConstruct指定init-method
@PreDestroy指定destroy-method

首先配置applicationContext.xml文件

<!-- 开启组件扫描 -->
<context:component-scan base-package="org.springioc.bean"/>

编写beanBook.java

package org.springioc.bean;

import org.springframework.stereotype.Component;

@Component//默认id为类名首字母小写;也可以设置固定的id,@Component("id")
public class Book {
	private String name;
	private int	num;
	
	public void execute() {
		System.out.println("book的execute方法!");
	}
	public void show() {
		System.out.println("name:"+name+", num:"+num);
	}
}

编写测试类,BookTest.java

package org.springioc.bean;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component//默认id为类名首字母小写;也可以设置固定的id,@Component("id")
@Scope("prototype")//设置单例或非单例,不设置默认为singleton
public class Book {
	private String name;
	private int	num;
	
	@PostConstruct//设置初始化方法
	public void init() {
		System.out.println("初始化方法!");
	}
	
	@PreDestroy//设置方法销户方法
	public void destroy() {
		System.out.println("销毁方法!");
	}
	
	public void execute() {
		System.out.println("book的execute方法!");
	}
}

  1. 注入注解
    @Resource:可以在变量定义前
    setXX方法前应用
    @Autowired:可以在变量定义前
    setXX方法前应用

一般使用时,功能等价,都可以实现注入。
如果不存在多个匹配类型,使用@Resource
或@Autowired都可以。
如果存在多个匹配类型,建议按名称注入
@Resource(name=“指定名称”)或
@Autowired
@Qualifier(“p”)

如果指定名称注入,不会再按类型匹配注入。

新建一个web工程
配置applicationContext.xml

<!-- 开启组件扫描 -->
<context:component-scan base-package="cn.springioc"/>

编写Phone.java,Computer.java,Student.java

package cn.springioc.bean;

import org.springframework.stereotype.Component;

@Component
public class Phone {
	public void show(){
		System.out.println("显示手机配置信息");
	}
}

package cn.springioc.bean;

import org.springframework.stereotype.Component;

@Component
public class Computer {
	
	public void show(){
		System.out.println("显示计算机配置信息");
	}
}

package cn.springioc.bean;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component("st")
public class Student {
	
	@Resource//首先根据名字phone去匹配,如果匹配不到就按照类型去匹配。这里根据phone匹配能够找到
	private Phone phone;
	
	public void setPhone(Phone phone) {
		this.phone = phone;
	}
	
	@Autowired//首先根据名字pc去匹配,如果匹配不到就按照类型去匹配。这里根据pc匹配找不到,就根据类型去匹配
	private Computer pc;
	
	public void setPc(Computer pc) {
		this.pc = pc;
	}
	
	public void show() {
		phone.show();
		pc.show();
	}

}

编写测试类StudentTest.java

package cn.springioc.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import cn.springioc.bean.Student;

public class StudentTest {

	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
		Student st = ac.getBean("st", Student.class);
		st.show();
	}

}

@Resouce(name=“id”),按照名字id去匹配,如果匹配不到不会按照类型去匹配,匹配不到就抛错

@Resource(name="pc1")//按照名字去匹配pc1,如果找不到就报错
	private Computer pc;
	public void setPc(Computer pc) {
		this.pc = pc;
	}

将Computer.java,的bean的id改为pc1,否则会抛错

@Component("pc1")
public class Computer {
	
	public void show(){
		System.out.println("显示计算机配置信息");
	}
}

@Autowired 和 @Qualifier(“id”)按照指定的id名字匹配

	@Autowired
	@Qualifier("pc1")
	private Computer pc;
	public void setPc(Computer pc) {
		this.pc = pc;
	}

或则

private Computer pc;
	@Autowired
	public void setPc(@Qualifier("pc1") Computer pc) {
		this.pc = pc;
	}
发布了23 篇原创文章 · 获赞 5 · 访问量 1483

猜你喜欢

转载自blog.csdn.net/zj499063104/article/details/94493866
今日推荐