当前位置: 首页 > news >正文

vue快速搭建网站自己做百度网站

vue快速搭建网站,自己做百度网站,中扶建设网站,成都商报官方网站🍓系列专栏:Spring系列专栏 🍉个人主页:个人主页 目录 一、bean基础配置 1.bean基础配置(id与class) 2.bean的name属性 3.bean作用范围scope配置 二、bean实例化 1.构造方法实例化 2.分析Spring的错误信息 3.静态工厂实例化 4.实例工厂 5.FactoryBean 三…

🍓系列专栏:Spring系列专栏

🍉个人主页:个人主页

目录

一、bean基础配置

1.bean基础配置(id与class)

2.bean的name属性

3.bean作用范围scope配置

二、bean实例化

1.构造方法实例化

2.分析Spring的错误信息

3.静态工厂实例化

4.实例工厂

5.FactoryBean

三、bean的生命周期

1.环境准备

2.生命周期设置

3.close关闭容器


通过前面两个案例,我们已经学习了 bean 如何定义配置 DI 如何定义配置 以及 容器对象如何获取 的内容,接下来主要是把这三块内容展开进行详细的讲解,深入的学习下这三部分的内容,首先是bean 基础配置。

一、bean基础配置

对于 bean 的配置中,主要会讲解 bean 基础配置 , bean 的别名配置 , bean的作用范围配置(重点) , 这三部分内容:

1.bean基础配置(idclass)

对于 bean 的基础配置,在前面的案例中已经使用过 :
 <bean id="" class=""/>
其中, bean 标签的功能、使用方式以及 id class 属性的作用,我们通过一张图来描述下

 这其中需要大家重点掌握的是:bean标签的idclass属性的使用

思考:

class属性能不能写接口如BookDao的类全名呢?

  • 答案肯定是不行,因为接口是没办法创建对象的。

2.beanname属性

首先来看下别名的配置说

 步骤1:配置别名

打开 spring 的配置文件 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"><!--name:为bean指定别名,别名可以有多个,使用逗号,分号,空格进行分隔--><bean id="bookService" name="service service4 bookEbi" class="com.itheima.service.impl.BookServiceImpl"><property name="bookDao" ref="bookDao"/></bean><!--scope:为bean设置作用范围,可选值为单例singloton,非单例prototype--><bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl" scope="prototype"/>
</beans>
说明 :Ebi 全称 Enterprise Business Interface ,翻译为企业业务接口
步骤 2: 根据名称容器中获取 bean 对象
public class AppForName {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookService bookService = (BookService) ctx.getBean("service4");bookService.save();}
}

运行:

 注意事项:

 如果不存在,则会报错,如下:

 获取bean无论是通过id还是name获取,如果无法获取到,将抛出异常 NoSuchBeanDefinitionException

3.bean作用范围scope配置

关于bean的作用范围是bean属性配置的一个重点内容。

看到这个作用范围,我们就得思考bean的作用范围是来控制bean哪块内容的? 我们先来看下bean作用范围的配置属性:

 验证IOC容器中对象是否为单例

验证思路
同一个 bean 获取两次,将对象打印到控制台,看打印出的地址值是否一致。
具体实现
创建一个 AppForScope 的类,在其 main 方法中来验证

结论:默认情况下,Spring创建的bean对象都是单例的

配置bean为非单例

在Spring配置文件中,配置scope属性来实现bean的非单例创建

  • Spring的配置文件中,修改<bean>scope属性
scope 设置为 singleton
<?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"><!--name:为bean指定别名,别名可以有多个,使用逗号,分号,空格进行分隔--><bean id="bookService" name="service service2 bookEbi" class="com.itheima.service.impl.BookServiceImpl"><property name="bookDao" ref="bookDao"/></bean><!--scope:为bean设置作用范围,可选值为单例singloton,非单例prototype--><bean id="bookDao" name="dao" class="com.itheima.dao.impl.BookDaoImpl"  scope="singleton"/>
</beans>

运行AppForScope,打印看结果:

 scope设置为prototype

结论,使用beanscope属性可以控制bean的创建是否为单例:
  • singleton默认为单例
  • prototype为非单例

scope 使用后续思考
为什么 bean 默认为单例 ?
  • bean为单例的意思是在SpringIOC容器中只会有该类的一个对象
  • bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高
bean 在容器中是单例的,会不会产生线程安全问题 ?
  • 如果对象是有状态对象,即该对象有成员变量可以用来存储数据的,
  • 因为所有请求线程共用一个bean对象,所以会存在线程安全问题。
  • 如果对象是无状态对象,即该对象没有成员变量没有进行数据存储的,
  • 因方法中的局部变量在方法调用完成后会被销毁,所以不会存在线程安全问题。
哪些 bean 对象适合交给容器进行管理 ?
  • 表现层对象
  • 业务层对象
  • 数据层对象
  • 工具对象

哪些bean对象不适合交给容器进行管理?

  • 封装实例的域对象,因为会引发线程安全问题,所以不适合。

二、bean实例化

对象已经能交给 Spring IOC 容器来创建了,但是容器是如何来创建对象的呢 ?
就需要研究下 bean 的实例化过程 ,在这块内容中主要解决两部分内容,分别是
  • bean是如何创建的
  • 实例化bean的三种方式,构造方法,静态工厂实例工厂
在讲解这三种创建方式之前,我们需要先确认一件事 :
bean 本质上就是对象,对象在 new 的时候会使用构造方法完成,那创建 bean 也是使用构造方法完成的。
基于这个知识点出发,我们来验证 spring bean 的三种创建方式

1.构造方法实例化

步骤 1: 准备需要被创建的类
准备一个 BookDao BookDaoImpl
public interface BookDao {public void save();
}
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}}
步骤 2: 将类配置到 Spring 容器
<?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="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
</beans>
步骤 3: 编写运行程序
public class AppForInstanceBook {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();}
}
步骤 4: 类中提供构造函数测试
BookDaoImpl 类中添加一个无参构造函数,并打印一句话,方便观察结果。
public class BookDaoImpl implements BookDao {public BookDaoImpl() {System.out.println("book dao constructor is running ....");}public void save() {System.out.println("book dao save ...");}}
运行程序,如果控制台有打印构造函数中的输出,说明 Spring 容器在创建对象的时候也走的是构造函数

步骤 5: 将构造函数改成 private 测试

运行程序,能执行成功 , 说明内部走的依然是构造函数 , 能访问到类中的私有构造方法 , 显而易见
Spring 底层用的是反射
步骤 6: 构造函数中添加一个参数测试
public class BookDaoImpl implements BookDao {private BookDaoImpl(int i) {System.out.println("book dao constructor is running ....");}public void save() {System.out.println("book dao save ...");}}
运行程序,
程序会报错,说明 Spring 底层使用的是类的无参构造方法。

2.分析Spring的错误信息

接下来,我们主要研究下Spring的报错信息来学一学如阅读。

错误信息从下往上依次查看,因为上面的错误大都是对下面错误的一个包装,最核心错误是在最下

Caused by: java.lang.NoSuchMethodException:
com.itheima.dao.impl.BookDaoImpl. <init> ()
  • Caused by 翻译为引起,即出现错误的原因
  • java.lang.NoSuchMethodException:抛出的异常为  没有这样的方法异常
  • com.itheima.dao.impl.BookDaoImpl. <init> ():哪个类的哪个方法没有被找到导致的异常,<init> ()指定是类的构造方法,即该类的无参构造方法

如果最后一行错误获取不到错误信息,接下来查看第二层:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bookDao' defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.itheima.dao.impl.BookDaoImpl]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.itheima.dao.impl.BookDaoImpl.<init>()

  • nested:嵌套的意思,后面的异常内容和最底层的异常是一致的
  • BeanInstantiationException:翻译为bean实例化异常
  • No default constructor found:没有一个默认的构造函数被发现

3.静态工厂实例化

接下来研究Spring中的第二种bean的创建方式静态工厂实例化:

工厂方式创建bean

在讲这种方式之前,我们需要先回顾一个知识点是使用工厂来创建对象的方式 :
(1) 准备一个 OrderDao OrderDaoImpl
public class OrderDaoImpl implements OrderDao {public void save() {System.out.println("order dao save ...");}
}
public interface OrderDao {public void save();
}
(2) 创建一个工厂类 OrderDaoFactory 并提供一个 静态方法
//静态工厂创建对象
public class OrderDaoFactory {public static OrderDao getOrderDao(){System.out.println("factory setup....");return new OrderDaoImpl();}
}
(3) 编写 AppForInstanceOrder 运行类,在类中通过工厂获取对象
public class AppForInstanceOrder {public static void main(String[] args) {//通过静态工厂创建对象OrderDao orderDao = OrderDaoFactory.getOrderDao();orderDao.save();}
}

 如果代码中对象是通过上面的这种方式来创建的,如何将其交给Spring来管理呢?

静态工厂实例化

这就要用到 Spring 中的静态工厂实例化的知识了,具体实现步骤为 :
(1) spring 的配置文件 application.properties 中添加以下内容 :
 <bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>
class: 工厂类的类全名
factory-mehod: 具体工厂类中创建对象的方法名
对应关系如下图

 (2)AppForInstanceOrder运行类,使用从IOC容器中获取bean的方法进行运行测试

public class AppForInstanceOrder {public static void main(String[] args) {//通过静态工厂创建对象
//        OrderDao orderDao = OrderDaoFactory.getOrderDao();
//        orderDao.save();ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");orderDao.save();}
}

4.实例工厂

接下来继续来研究Spring的第三种bean的创建方式实例工厂实例化:

环境准备

(1) 准备一个 UserDao UserDaoImpl
public interface UserDao {public void save();
}
public class UserDaoImpl implements UserDao {public void save() {System.out.println("user dao save ...");}
}
(2) 创建一个工厂类 OrderDaoFactory 并提供一个普通方法,注意此处和静态工厂的工厂类不一样的
地方是方法不是静态方法
//实例工厂创建对象
public class UserDaoFactory {public UserDao getUserDao(){return new UserDaoImpl();}
}
(3) 编写 AppForInstanceUser 运行类,在类中通过工厂获取对象
public class AppForInstanceUser {public static void main(String[] args) {//创建实例工厂对象UserDaoFactory userDaoFactory = new UserDaoFactory();//通过实例工厂对象创建对象UserDao userDao = userDaoFactory.getUserDao();userDao.save();}
}
运行后,可以查看到结果

对于上面这种实例工厂的方式如何交给Spring管理呢?

实例工厂实例化  

具体实现步骤为 :
(1) spring 的配置文件中添加以下内容 :
<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/>
<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
实例化工厂运行的顺序是 :
  • 创建实例化工厂对象,对应的是第一行配置
  • 调用对象中的方法来创建bean,对应的是第二行配置
  • factory-bean: 工厂的实例对象
  • factory-method:工厂对象中的具体创建对象的方法名 , 对应关系如下 :

 factory-mehod:具体工厂类中创建对象的方法名

(2)AppForInstanceUser运行类,使用从IOC容器中获取bean的方法进行运行测试

public class AppForInstanceUser {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userDao = (UserDao) ctx.getBean("userDao");userDao.save();}
}

 实例工厂实例化的方式就已经介绍完了,配置的过程还是比较复杂,所以Spring为了简化这种配置方式就提供了一种叫FactoryBean的方式来简化开发。

5.FactoryBean

具体的使用步骤为 :
(1) 创建一个 UserDaoFactoryBean 的类,实现 FactoryBean 接口,重写接口的方法
//FactoryBean创建对象
public class UserDaoFactoryBean implements FactoryBean<UserDao> {//代替原始实例工厂中创建对象的方法public UserDao getObject() throws Exception {return new UserDaoImpl();}public Class<?> getObjectType() {return UserDao.class;}}
(2) Spring 的配置文件中进行配置
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
(3)AppForInstanceUser 运行类不用做任何修改,直接运行

这种方式在 Spring 去整合其他框架的时候会被用到,所以这种方式需要大家理解掌握。
查看源码会发现, FactoryBean 接口其实会有三个方法,分别是 :
 getObject() throws Exception;Class<?> getObjectType();default boolean isSingleton() {return true;}
方法一 :getObject() ,被重写后,在方法中进行对象的创建并返回
方法二 :getObjectType(), 被重写后,主要返回的是被创建类的 Class 对象
方法三 : 没有被重写,因为它已经给了默认值,从方法名中可以看出其作用是设置对象是否为单例,默认true ,从意思上来看,我们猜想默认应该是单例,如何来验证呢 ?
思路很简单,就是从容器中获取该对象的多个值,打印到控制台,查看是否为同一个对象。
public class AppForInstanceUser {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userDao1 = (UserDao) ctx.getBean("userDao");UserDao userDao2 = (UserDao) ctx.getBean("userDao");System.out.println(userDao1);System.out.println(userDao2);
//        userDao.save();}
}
打印结果,如下 :

通过验证,会发现默认是单例,那如果想改成单例具体如何实现?

只需要将 isSingleton() 方法进行重写,修改返回为 false ,即可
public class UserDaoFactoryBean implements FactoryBean<UserDao> {public UserDao getObject() throws Exception {return new UserDaoImpl();}public Class<?> getObjectType() {return UserDao.class;}public boolean isSingleton() {return false;}}
重新运行 AppForInstanceUser ,查看结果

从结果中可以看出现在已经是非单例了,但是一般情况下我们都会采用单例,也就是采用默认即可。所以isSingleton() 方法一般不需要进行重写。

三、bean的生命周期

关于 bean 的相关知识还有最后一个是 bean 的生命周期 , 对于生命周期,我们主要围绕着 bean 生命周期控制来讲解 :
首先理解下什么是生命周期 ?
  • 从创建到消亡的完整过程,例如人从出生到死亡的整个过程就是一个生命周期。
bean 生命周期是什么 ?
  • bean对象从创建到销毁的整体过程。
构造方法 bean 生命周期控制是什么 ?
  • bean创建后到销毁前做一些事情。
现在我们面临的问题是如何在 bean 的创建之后和销毁之前把我们需要添加的内容添加进去。

1.环境准备

项目结构: 

(1)项目中添加BookDaoBookDaoImplBookServiceBookServiceImpl

public interface BookDao {public void save();
}
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
public class BookServiceImpl implements BookService{
private BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
(2)resources 下提供 spring 的配置文件
<?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="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
</beans>
(3) 编写 AppForLifeCycle 运行类,加载 Spring IOC 容器,并从中获取对应的 bean 对象
public class AppForLifeCycle {public static void main( String[] args ) {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();}
}

2.生命周期设置

接下来,在上面这个环境中来为 BookDao 添加生命周期的控制方法,具体的控制有两个阶段 :
  • bean创建之后,想要添加内容,比如用来初始化需要用到资源
  • bean销毁之前,想要添加内容,比如用来释放用到的资源

步骤1:添加初始化和销毁方法

针对这两个阶段,我们在 BookDaoImpl 类中分别添加两个方法, 方法名任意
public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}//表示bean初始化对应的操作public void init(){System.out.println("init...");}//表示bean销毁前对应的操作public void destory(){System.out.println("destory...");}}

步骤2:配置生命周期

在配置文件添加配置,如下 :
  <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory" ></bean>
运行程序

从结果中可以看出, init 方法执行了,但是 destroy 方法却未执行,这是为什么呢 ?
  • SpringIOC容器是运行在JVM
  • 运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器获取bean对象,然后调方 法执行
  • main方法执行完后,JVM退出,这个时候IOC容器中的bean还没有来得及销毁就已经结束了 所以没有调用对应的destroy方法
知道了出现问题的原因,具体该如何解决呢 ?

3.close关闭容器

 调用ctxclose()方法

public class AppForLifeCycle {public static void main( String[] args ) {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();ctx.close();}
}
运行程序,就能执行 destroy 方法的内容:

注册钩子关闭容器
  • 在容器未关闭之前,提前设置好回调函数,让JVM在退出之前回调此函数来关闭容器
  • 调用ctxregisterShutdownHook()方法
public class AppForLifeCycle {public static void main( String[] args ) {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();
//        注册关闭钩子函数,在虚拟机退出之前回调此函数,关闭容器ctx.registerShutdownHook();}
}

两种方式介绍完后, close registerShutdownHook 选哪个 ?
相同点 : 这两种都能用来关闭容器
不同点 :close() 是在调用的时候关闭, registerShutdownHook() 是在 JVM 退出前调用关闭。
分析上面的实现过程,会发现添加初始化和销毁方法,即需要编码也需要配置,实现起来步骤比较多也比较乱。
Spring 提供了两个接口来完成生命周期的控制,好处是可以不用再进行配置 init - method 和destroy- method
接下来在 BookServiceImpl 完成这两个接口的使用 :
修改BookServiceImpl 类,添加两个接口 InitializingBean DisposableBean 并实现接口中的
两个方法 afterPropertiesSet destroy
public class BookServiceImpl implements BookService,InitializingBean,DisposableBean
{private BookDao bookDao;public void setBookDao(BookDao bookDao) {System.out.println("set .....");this.bookDao = bookDao;}public void save() {System.out.println("book service save ...");bookDao.save();}public void destroy() throws Exception {System.out.println("service destroy");}public void afterPropertiesSet() throws Exception {System.out.println("service init");}
}
pox.xml:
  <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><property name="bookDao" ref="bookDao"/></bean>

重新运行 AppForLifeCycle

 

bean 生命周期小结
(1) 关于 Spring 中对 bean 生命周期控制提供了两种方式 :
  • 在配置文件中的bean标签中添加init-methoddestroy-method属性
  • 类实现InitializingBeanDisposableBean接口,这种方式了解下即可。
(2) 对于 bean 的生命周期控制在 bean 的整个生命周期中所处的位置如下 :
初始化容器
  • 1.创建对象(内存分配)
  • 2.执行构造方法
  • 3.执行属性注入(set操作)
  • 4.执行bean初始化方法
使用 bean
  • 1.执行业务操作
关闭 / 销毁容器
  • 1.执行bean销毁方法
(3) 关闭容器的两种方式 :
ConfigurableApplicationContext ApplicationContext 的子类
  • close()方法
  • registerShutdownHook()方法
http://www.yayakq.cn/news/957003/

相关文章:

  • 贵阳模板做网站wordpress数据库结构
  • 网站的建设时间中建集团官网
  • 大连设计网站公司广告制作费和广告服务费区别
  • 广西建设职业学院技术教务系统网站可以做软文推广的网站
  • 什么是网站服务器名称个人网站建站系统
  • 免费微场景制作网站深圳专业高端网站建设费用
  • 中国建设银行注册网站用户名怎么填微信 微网站
  • 怎么查看一个网站是用什么程序做的金融网站开发
  • 沛县可以做网站的单位网页游戏排行榜前十平台
  • 微信做网站支付工具中小企业网站建设调研报告
  • 网页设计怎么创建站点自己做的网站什么时候可以赚钱
  • 济南网站建设的费用郑州官方最新通告
  • 帝国cms关闭网站网站建设项目书
  • wordpress 整站采集流行用什么做网站
  • 网站网站合作建设电子元件做的比较好的网站
  • 怎样利用网站做推广婚纱网站论文
  • 北京企业建站技术iis7.5 没有默认网站
  • 销售单页网站wordpress用户权限插件
  • 岳阳网站建设设计诺盾网站建设
  • 重庆的网站建设公司济宁网站建设价格
  • 网站节约化建设金融公司网站规划方案
  • 微企点做网站怎么样品牌建设演讲稿
  • 一学一做教育视频网站有哪些内容莱芜金点子信息港二手市场
  • 网站文字变白色代码怎么做引导企业做网站
  • 产品展示网站设计百度关键词seo排名优化
  • 茂名整站优化做的网站为什么图片看不了怎么办
  • 青岛红岛做网站成都住房和城乡建设局 网站
  • 中国最受欢迎的网站怎么在一个网站做多个页面
  • 网站换域名 百度收录dw网站制作素材
  • 网站建设案例图片wordpress本地怎么搬家