一.Spring的认识
轻量级的DI/IOC与AOP的容器框架
- DI /IOC: 依赖注入/控制反转
- 轻量级 : 使用简单,运行容易,功能强大
- AOP: 面向切面编程
作用 : 解耦 , 集成其它框架,让咱们代码更加的优雅,多人开发更加容易
二. Hello-Spring
①.导包 ②.配置文件 ③. 启动框架
2.1 导包
-
核心包 core(核心),bean,context(上下文),expression(表示式)
-
依赖包 logging
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QuxBovB2-1604054540218)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200923113548256.png)]
2.2 写配置文件
2.2.1 准备类
public class HelloBean {
HelloBean(){
System.out.println("来啊,创建我啊!!!!!");
}
}
2.2.2 配置文件 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">
<!--
bean:告诉Spring,帮咱们创建一个bean对象
id:唯一的名称(咱们需要通过这个名字拿到这个bean对象)
class:你需要通过哪个类创建对象(Spring会自己通过反射帮你把这个类创建出来)
-->
<bean id="hello" class="cn.itsouce._01_hello.HelloBean"></bean>
</beans>
2.3 启动框架
2.3.1 方式一:BeanFactroy
/**
* ctrl+t : 查看类结构
* 注:现在要做的是启动Spring这个框架
* 启动就两步:①.读取配置文件 ②.创建核心对象(BeanFactory)
*/
@Test
public void testRun01() throws Exception {
//1.读取配置文件:applicationContext.xml
// Resource是一个接口,我们只能选择它的一个子类来创建
Resource resource = new ClassPathResource("applicationContext.xml");
//2.拿到核心对象
// BeanFactory是一个接口,不能直接new出来
// 所以我们选择了它的一个子类:XmlBeanFactory(支持xml配置文件)
// 我们要创建XmlBeanFactory,要求必需传一个Resource
BeanFactory factory = new XmlBeanFactory(resource);
//3.获取咱们需要的对象 从工厂中获取我们需要的bean对象
System.out.println(factory.getBean("hello"));
}
2.3.2 方式二 ApplicationContext
/**
* 注:现在要做的是启动Spring这个框架
* 启动就两步:①.读取配置文件 ②.创建核心对象(BeanFactory)
* ApplicationContext:应用上下文
*/
@Test
public void testRun02() throws Exception {
//1.创建ApplicationContext对象
// 它是一个接口,我们只能创建它的实现类
// ApplicationContext也是一个BeanFactory(它是BeanFactory的子接口)
ApplicationContext ac =
new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取需要的对象
System.out.println(ac.getBean("hello"));
}
2.3.3 BeanFactory
与ApplicationContext
的区别
ApplicationContext
是BeanFactory
的子接口,功能更加强大(国际化,读取资源,邮件,模板)BeanFactory
:懒加载(使用的时候才创建bean对象)ApplicationContext
:迫切加载
2.3.4 获取bean的三种方式
- 根据名称
ac.getBean("hello")
需要强转 - 根据类型
ac.getBean(HelloBean.class)
相同类型只能唯一 - 名称+类型
ac.getBean("hello", HelloBean.class)
三. 依赖注入
开发前准备两个类 :
MyBean
,YouBean
3.1 xml注入
3.1.1 配置相应的bean,并且注入属性
<!-- 配置一个mybean -->
<bean id="my" class="cn.itsouce._02_di.MyBean">
<!--
注入一个属性
告诉Spring,我有一个属性叫作youBean,把你那个you的对象给注入进来
name:当前MyBean中的属性性 注意:getter,setter才是属性
ref:引用(一般是某一个bean的名称)
-->
<property name="youBean" ref="you"></property>
</bean>
<!-- 配置一个youbean -->
<bean id="you" class="cn.itsouce._02_di.YouBean"></bean>
3.1.2 在Bean提供属性
注 : setXxx 才是Bean对象的属性
public class MyBean {
/**
* 我们要使用Spring的注入功能
* 我们自己不创建这个对象,而让Spring把这个对象给注入进来
* @Autowired:自动注入,spring只要看到了就会把对象交给你 -> Spring独有的
* 找对象顺序:@Qualifier("you"),youBean:名字,YouBean:类型
* @Resource:和@Autowired效果是一样的 -> JDK提供,Spring实现
*/
//@Autowired
private YouBean youBean;
//注: setXxxx才是属性
public void setYouBean(YouBean youBean) {
this.youBean = youBean;
}
public void say(){
System.out.println("hello,"+youBean);
}
}
3.2 注解注入
@Autowired
private YouBean youBean;
- 先通过名称,现通过类型来获取对象
@Resource
效果一样(jdk提供的),还是建议使用@Autowired
如果我们想完全自己来确定根据哪个名称注入,怎么做?
@Autowired
@Qualifier("you")
private YouBean youBean;
@Resource(name="you")
四. Spring测试功能
4.1 导包
- test :Spring的测试包
- aop :Spring面向切面包(测试需要用到)
4.2 配置注解与路径
@RunWith(SpringJUnit4ClassRunner.class)
:Spring和测试一起启动@ContextConfiguration
:获取核心配置文件的路径- 如果没有写路径,默认会到当前位置找到
类名-Context.xml
的文件 - 加上classpath: 会到资源根路径下找文件
- 不加classpath: 相对路径下找文件
- 如果没有写路径,默认会到当前位置找到
/**
*
* @RunWith:和谁一起运行
* SpringJUnit4ClassRunner.class:Spring和Junit4一起运行的类
* @ContextConfiguration:上下文配置 -> 找配置文件
* classpath: xx.xml:到资源根路径下查询对应的xml文件
* 不写classpath就是相对路径
* 如果不写路径,它会默认在当前位置去找一个 (类名-Context.xml-》SpringTest-Context.xml)的文件
* 默认使用ApplicationContext的方案:迫切加载
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class SpringTest {
@Autowired
YouBean youBean;
@Test
public void testSpring() throws Exception {
System.out.println(youBean);
}
}
五. 配置细节学习
5.1 Spring中Bean的作用域
-
咱们只关心两个作用域: 单例,多例
-
单例 : 是默认的,Spring创建好bean后,把bean放到容器后,一直使用的都是它
-
多例 : 每次使用单独创建一个给你
咱们怎么把一个Bean对象配置成多例的对象
scope="prototype"
<!-- Spring创建的Bean对象,默认是单例的 咱们可以修改 scope来设置的作用域 scope="prototype":这个bean对象就会变成多例 --> <bean id="scopeBean" class="cn.itsource._04_scope.ScopeBean" scope="prototype"></bean>
5.2 懒加载的配置
- 咱们现在使用Spring,默认都是迫切加载
- 懒加载配置有两种: 全局,单独配置
- 全局配置
<beans ... default-lazy-init="true" />
- 局部配置
<bean ... lazy-init="true" >
- 全局配置
5.3 生命周期的认识
- 咱们可以自己去控制一个类在创建后以及销毁前执行的方法
5.3.1 创建一个类
public class LifeBean {
//构造实例
LifeBean(){
System.out.println("出生,被创建出来的生命....");
}
//初始化方法
// Spring创建完对象后执行这个方法做一些初始化的操作
public void init(){
System.out.println("取个名,上个户,你就是中国好公民...");
}
//销毁方法
public void destory(){
System.out.println("我还有100没用完.....");
}
}
5.3.2 配置生命周期方法
<!--
需要自己告诉Spring:创建对象后要做的初始化工作(要执行哪一个方法)
init-method:Spring创建对象后会去执行的方法
destroy-method:Bean对象被销毁前要执行的方法(多例该配置无效)
-->
<bean id="life" class="cn.itsource._06_life.LifeBean"
init-method="init" destroy-method="destory" ></bean>
注 : 如果这个bean是多例的,销毁配置无效
六. Spring中的三层
大家练一练,记住一个点 : Web环境中怎么启动Spring
-
导包 : web
-
配置一个监听器:
ContextLoaderListener
- 监听服务器启动,一旦启动,就是Spring也启动
- 默认到
WEB-INF
下面去找applicationContext.xml
文件
-
自己配置
applicationContext.xml
文件的位置(不使用默认)
<!--
java.io.FileNotFoundException:
Could not open ServletContext resource [/WEB-INF/applicationContext.xml]
上面这个错:不能够找到对应的xml配置文件
默认是到WEB-INF下面去找applicationContext.xml文件
解决方案1:把applicationContext.xml文件放到WEB-INF下面(不建议这么做)
解决方案2:自定义xml的位置(需要做一个全局配置)
ContextLoaderListener监听器会到web.xml中读取核心配置文件
-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--
javaweb三大组件:Servlet(小程序),Filter(过滤器),Listener(监听器)
Spring做了一个监听器,监听服务器(tomcat)启动
一旦服务器启动,Spring也自已把自己启动起来
Spring已经做好了这个监听器,我们只需配置即可:ContextLoaderListener
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
今天学习Spring的完整导包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ln14xpSJ-1604054540228)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200923170138166.png)]
七.其它
7.1 面试题
请问:BeanFactory与ApplicationContext有什么区别?
ApplicationContext是BeanFactroy的一个子接口,它的功能要更加强大一些!
它支持:读取资源,国际化,邮件发送等等功能
BeanFactory:是懒加载(使用的时候才创建相应的bean)
ApplicationContext:迫切加载(直接创建)
7.2 常见错误
ClassNotFoundException:某个类没有找到
一般只有两个原因:导包的问题,
你自己一个全限定名写错了
NoUniqueBeanDefinitionException:这个Bean的类型不是唯一的
org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [cn.itsouce._01_hello.HelloBean] is defined:
expected single matching bean but found 2: hello2,hello
我只能配置一个bean,但是却发现两个
7.2 常见错误
ClassNotFoundException:某个类没有找到
一般只有两个原因:导包的问题,
你自己一个全限定名写错了
NoUniqueBeanDefinitionException:这个Bean的类型不是唯一的
org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [cn.itsouce._01_hello.HelloBean] is defined:
expected single matching bean but found 2: hello2,hello
我只能配置一个bean,但是却发现两个