一、Spring核心概念
1.1IoC(Inversion of Contral):控制反转
- 代码书写现状
- 耦合度偏高
- 解决方案
- 使用对象时,在程序中不要主动使用new产生对象,转换为由外部提供对象
- IoC(Inversion of Contral):控制反转
- 对象的创建控制权由程序转移到外部,这种思想称为控制反转
- Spring技术对IoC思想进行了实现
- Spring提供了一个容器,称为IoC容器,用来充当IoC思想中的“外部”
- IoC容器负责对象的创建、初始化等一系列工作,被创建或被管理的对象在IoC容器中统称为Bean
- DI(Dependency Injection)依赖注入
- 在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入
1.2IoC代码实现
- 1.导入Spring坐标
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.21.RELEASE</version> </dependency>
- 2.定义Spring管理类
package com.practice.dao; /** * @Author YJ * @Date 2023/7/25 11:26 * Description: */ public interface BookDao { void save(); }
package com.practice.service; /** * @Author YJ * @Date 2023/7/25 11:28 * Description: */ public interface BookService { void save(); }
package com.practice.service.impl; import com.practice.dao.BookDao; import com.practice.dao.impl.BookDaoImpl; import com.practice.service.BookService; /** * @Author YJ * @Date 2023/7/25 11:28 * Description: */ public class BookServiceImpl implements BookService { private BookDao bookDao = new BookDaoImpl(); public void save() { bookDao.save(); } }
- 3.创建Spring配置文件
applicationContext.xml
,配置对应类作为Spring管理的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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--1.导入spring的坐标spring-context,对应的版本号是5.2.21.RELEASE--> <!--2.配置bean--> <bean id="bookDao" class="com.practice.dao.impl.BookDaoImpl"/> <bean id="bookService" class="com.practice.service.impl.BookServiceImpl"/> </beans>
- 4.初始化IoC容器(Spring核心容器/Spring容器),通过容器获取bean
public class App { public static void main(String[] args) { //获取IoC容器 ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取bean /*BookDao bookDao = (BookDao) act.getBean("bookDao"); bookDao.save();*/ BookService bookService = (BookService) act.getBean("bookService"); bookService.save(); } }
1.2DI代码实现
- 1.删除业务层中使用
new
的方式创建的dao对象 - 2.提供对应的
setter
方法 - 3.配置
service
与dao的关系
property
标签表示配置当前bean的属性name
属性表示配置哪一个具体的属性ref
属性表示参照哪一个bean
package com.practice.service.impl; import com.practice.dao.BookDao; import com.practice.service.BookService; public class BookServiceImpl implements BookService { //删除业务层中使用new的方式创建的dao对象 private BookDao bookDao; public void save() { bookDao.save(); } //提供对应的set方法 public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } }
<?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"> <!--1.导入spring的坐标spring-context,对应的版本号是5.2.21.RELEASE--> <!--2.配置bean--> <bean id="bookDao" class="com.practice.dao.impl.BookDaoImpl"/> <bean id="bookService" class="com.practice.service.impl.BookServiceImpl"> <!--配置service与dao的关系--> <!--property标签表示配置当前bean的属性--> <!--name属性表示配置哪一个具体的属性--> <!--ref属性表示参照哪一个bean--> <property name="bookDao" ref="bookDao"/> </bean> </beans>
二、bean的相关操作
2.1bean的配置
2.1.1bean的基础配置
- 1.功能: 定义Spring核心容器管理的对象
- 2.格式:
<beans> <bean/> <bean></bean> </beans>
- 3.属性:
- 3.1id: bean的id,使用容器可以通过id值获取对应的bean,在一个容器中id值唯一
- 3.2class: bean的类型,即配置的bean的全路径类名
2.1.2bean的别名配置
- 别名配置就是在bean标签中添加一个name属性,这个name属性就是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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!--1.导入spring的坐标spring-context,对应的版本号是5.2.21.RELEASE--> <!--2.配置bean--> <bean id="bookDao" class="com.practice.dao.impl.BookDaoImpl"/> <!--name起别名--> <bean id="bookService" name="service" class="com.practice.service.impl.BookServiceImpl"> <!--配置service与dao的关系--> <!--property标签表示配置当前bean的属性--> <!--name属性表示配置哪一个具体的属性--> <!--ref属性表示参照哪一个bean--> <property name="bookDao" ref="bookDao"/> </bean> </beans>
package com.practice; import com.practice.dao.BookDao; import com.practice.service.BookService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @Author YJ * @Date 2023/7/25 11:33 * Description: */ public class App { public static void main(String[] args) { //获取IoC容器 ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取bean /*BookDao bookDao = (BookDao) act.getBean("bookDao"); bookDao.save();*/ BookService bookService = (BookService) act.getBean("service");//用到别名service bookService.save(); } }
- 若是bean的名称跟配置的不一致会出现
NoSuchBeanDefinitionException
异常,表示该bean未定义
public class App { public static void main(String[] args) { //获取IoC容器 ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取bean /*BookDao bookDao = (BookDao) act.getBean("bookDao"); bookDao.save();*/ BookService bookService = (BookService) act.getBean("service1");//用到错误别名service1 bookService.save(); } }
2.1.3bean的作用范围配置
- Spring默认配置的bean是一个单列的,即只有一个bean对象,如下所示:
public class AppForScope { public static void main(String[] args) { //获取IoC容器 ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml"); BookDao bookDao1 = (BookDao) act.getBean("bookDao"); BookDao bookDao2 = (BookDao) act.getBean("bookDao"); System.out.println(bookDao1); System.out.println(bookDao2); } }
- 我们可以通过配置bean的文件控制是否产生一个对象还是多个对象
- 通过
scope
属性定义bean的作用范围,可选范围如下:
singleton
:单例(默认)prototype
:非单例
- 适合交给容器进行管理的bean
- 表现层对象
- 业务层对象
- 数据层对象
- 工具对象
- 不适合交给容器进行管理的bean
- 封装实体的域对象
2.2bean的实例化 - - 构造方法
- bean本质上就是对象,创建bean使用构造方法完成
public class BookDaoImpl implements BookDao { private BookDaoImpl() { System.out.println("book dao constructor running..."); } public void save() { System.out.println("bookDao save~"); } }
public class App { public static void main(String[] args) { //获取IoC容器 ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取bean BookDao bookDao = (BookDao) act.getBean("bookDao"); bookDao.save(); } }
<?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"> <!--1.导入spring的坐标spring-context,对应的版本号是5.2.21.RELEASE--> <!--2.配置bean--> <bean id="bookDao" class="com.practice.dao.impl.BookDaoImpl" scope="prototype"/> <!--name起别名--> <bean id="bookService" name="service" class="com.practice.service.impl.BookServiceImpl" > <!--配置service与dao的关系--> <!--property标签表示配置当前bean的属性--> <!--name属性表示配置哪一个具体的属性--> <!--ref属性表示参照哪一个bean--> <property name="bookDao" ref="bookDao"/> </bean> </beans>
- 表明bean在创建时调用的无参构造方法
- 无参构造方法如果不存在,会抛出
BeanCreationException
异常
2.3bean的实例化 - - 实例工厂与FactoryBean
<?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"> <!--1.导入spring的坐标spring-context,对应的版本号是5.2.21.RELEASE--> <!--2.配置bean--> <!--方式三:使用实例化工厂实例化bean--> <bean id="userFactory" class="com.practice.factory.UserDaoFactory"/> <bean id="userDao" factory-bean="userFactory" factory-method="getUserDao"/> </beans>
public interface UserDao { public void save(); }
public class UserDaoImpl implements UserDao { public void save() { System.out.println("UserDao save..."); } }
public class UserDaoFactory { public UserDao getUserDao(){ return new UserDaoImpl(); } }
package com.practice; import com.practice.dao.UserDao; import com.practice.factory.UserDaoFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @Author YJ * @Date 2023/7/25 19:09 * Description: */ public class AppForInstanceUser { public static void main(String[] args) { /*//创建实例工厂对象 UserDaoFactory userDaoFactory = new UserDaoFactory(); UserDao userDao = userDaoFactory.getUserDao(); userDao.save();*/ //获取IoC容器 ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取bean UserDao userDao = (UserDao) act.getBean("userDao"); userDao.save(); } }
- 使用FactoryBean实例化bean
package com.practice.factory; import com.practice.dao.UserDao; import com.practice.dao.impl.UserDaoImpl; import org.springframework.beans.factory.FactoryBean; /** * @Author YJ * @Date 2023/7/25 19:21 * Description:使用FactoryBean实例化bean */ public class UserDaoFactoryBean implements FactoryBean<UserDao> { public UserDao getObject() throws Exception { //代替原始实例工厂中创建对象的方法 return new UserDaoImpl(); } public Class<?> getObjectType() { return UserDao.class; } }
<?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--> <bean id="userFactory" class="com.practice.factory.UserDaoFactory"/> <bean id="userDao1" factory-bean="userFactory" factory-method="getUserDao"/> <!--方式四:使用FactoryBean实例化bean--> <bean id="userDao" class="com.practice.factory.UserDaoFactoryBean"/> </beans>
- 使用这种方式创建出的bean是单例的
- 可在
UserDaoFactoryBean
中实现方法isSingleton
并返回false
即可
public boolean isSingleton() { return false; }
2.4bean的生命周期
- 生命周期:从创建到消亡的完整过程
- bean生命周期:bean从创建到消毁的整体过程
- bean生命周期控制:在bean创建后到销毁前做一些事情
package com.practice.dao.impl; import com.practice.dao.BookDao; /** * @Author YJ * @Date 2023/7/25 11:24 * Description: */ public class BookDaoImpl1 implements BookDao { public void save() { System.out.println("bookDao save~"); } //表示bean初始化 public void init() { System.out.println("init..."); } //表示bean销毁前对应操作 public void destroy() { System.out.println("destroy..."); } }
<?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--> <!--<bean id="userFactory" class="com.practice.factory.UserDaoFactory"/>--> <!--<bean id="userDao1" factory-bean="userFactory" factory-method="getUserDao"/>--> <!--方式四:使用FactoryBean实例化bean--> <!--<bean id="userDao" class="com.practice.factory.UserDaoFactoryBean"/>--> <!--配置bean的生命周期--> <bean id="bookDao" class="com.practice.dao.impl.BookDaoImpl1" init-method="init" destroy-method="destroy"/> </beans>
package com.practice; import com.practice.dao.BookDao; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @Author YJ * @Date 2023/7/25 19:40 * Description: */ public class AppForLifeCycle { public static void main(String[] args) { //获取IoC容器 ClassPathXmlApplicationContextact = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取bean BookDao bookDao = (BookDao) act.getBean("bookDao"); bookDao.save(); //关闭容器,才能看到destory方法的执行结果 //1.暴力关闭 act.close(); //2.关闭钩子 act.registerShutdownHook(); } }
package com.practice.service.impl; import com.practice.dao.BookDao; import com.practice.dao.impl.BookDaoImpl1; import com.practice.service.BookService; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; /** * @Author YJ * @Date 2023/7/25 11:28 * Description: */ public class BookServiceImpl1 implements BookService, InitializingBean, DisposableBean { private BookDao bookDao; public void save() { System.out.println("bookService save..."); bookDao.save(); } public void afterPropertiesSet() throws Exception { System.out.println("service init..."); } public void destroy() throws Exception { System.out.println("service destroy..."); } public void setBookDao(BookDaoImpl1 bookDao) { this.bookDao=bookDao; } }
package com.practice; import com.practice.dao.BookDao; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @Author YJ * @Date 2023/7/25 19:40 * Description: */ public class AppForLifeCycle { public static void main(String[] args) { //获取IoC容器 ClassPathXmlApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml"); //获取bean BookDao bookDao = (BookDao) act.getBean("bookDao"); bookDao.save(); //act.close(); act.registerShutdownHook(); } }
<?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--> <!--<bean id="userFactory" class="com.practice.factory.UserDaoFactory"/>--> <!--<bean id="userDao1" factory-bean="userFactory" factory-method="getUserDao"/>--> <!--方式四:使用FactoryBean实例化bean--> <!--<bean id="userDao" class="com.practice.factory.UserDaoFactoryBean"/>--> <!--配置bean的生命周期--> <bean id="bookDao" class="com.practice.dao.impl.BookDaoImpl1" init-method="init" destroy-method="destroy"/> <bean id="bookService" class="com.practice.service.impl.BookServiceImpl1"> <property name="bookDao" ref="bookDao"/> </bean> </beans>
总结
关于Spring的初步认识我们就学到这里了,关于bean的操作我们有了基本的认识,欢迎各位小伙伴点赞+关注!!!