总结41 Spring框架的概念与应用 第一系列
概念
准备工作
一.导入Jar包到Mevan
在配pom.xml配置文件中进行依赖管理,即:从本地或网络仓库中,把spring的jar引用过来
自用模板:
<!-- 导入Spring框架 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
二.创建Spring配置文件
我们必须通过xml配置文件来定义Spring框架的应用规则,要使用Spring框架,必须使用配置文件。
配置文件名任意,格式为xml,但圈内共识的配置文件名为:applicationContext
如果你是用maven模式,那么需要将xml文件创建在resources目录下。
如果你是用普通模式,那么需要将xml文件创建在src目录下。
三.配置Bean基本标签(必须)
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"></bean>
*id:Bean实例在Spring容器中的唯一标识
class:Bean的全限定名称
四.配置Bean标签范围(了解)
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" scope="singleton" ></bean>
scope:指对象的作用范围,取值如下:
单例 singleton:主要要求每个人对同一个实体类,都用到了相同的对象(实际开发中多用)
多例 prototype:要求每个人对同一个实体类,都用到了各自不同的对象
这个是面试题,关于单例(singleton)和多例(prototype)什么时候创建反射的对象.
单例的创建对象:一旦加载配置文件(ApplicationContext ac =
new ClassPathXmlApplicationContext(“applicationContext.xml”))就会创建对象
五.Bean生命周期配置(了解)
**init-method:**指定类中的初始化方法名称,当对象被创建时,调用该方法。
**destroy-method:**指定类中销毁方法名称,当对象被销毁时,调用该方法。
六.Bean实例化三种方式
1) 使用无参构造方法实例化
默认调用无参构造方法创建对象,如果bean中没有默认无参构造函数,将会创建失败
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
2) 工厂静态方法实例化
//工厂类
public class StaticFactoryBean {
//静态方法,通过该方法获取对象
public static UserDao createUserDao(){
return new UserDaoImpl();
}
}
<!-- 调用StaticFactoryBean类的静态方法createUserDao获取对象 -->
<bean id="userDao" class="com.itheima.factory.StaticFactoryBean"
factory-method="createUserDao" />
3) 工厂实例方法实例化
//工厂类
public class DynamicFactoryBean {
//非静态方法,需要先创建工厂类的对象,再通过对象调用该方法,获取对象
public UserDao createUserDao(){
return new UserDaoImpl();
}
}
<!-- 创建工厂类的对象 -->
<bean id="factoryBean" class="com.itheima.factory.DynamicFactoryBean"/>
<!-- 通过工厂类的对象,调用createUserDao方法,获取UserDao对象 -->
<bean id="userDao" factory-bean="factoryBean" factory-method="createUserDao"/>
控制反转
概念
Spring框架能帮我们实现很多东西,它的原理都是基于反射Class字节码文件。
再今天的第一系列中,我们来讲讲Spring的最大用途之一,那就是’动态地反射Class字节码文件‘
动态反射字节码文件有什么用处呢?打个比方,如果定义了一个SQL功能的Dao实现类,它叫做’DaoA’,但是后来你要进行SQL功能升级,那么意味着就需要新创建一个SQL功能的Dao实现类,它叫做’DaoB’。
但问题是此时,Service已经指定为调用旧的Dao实现类’DaoA’,如果要更改为调用新的Dao实现类’DaoB‘,那么就需要先把Java项目停下来然后去更改源码。但问题就出现在’需要停止Java项目来更改源码‘,如果我们运行的是一个WEB项目呢?一旦网站停止的话,那么就会造成很多损失。此时,Spring框架的作用就凸显出来了,那就是’能够让项目在不停止的情况下,将Service调用的Dao实现类,由’DaoA’,改为’DaoB‘‘。这有个术语,叫做’控制反转‘
应用
步骤一:配置Bean标签
格式:<bean id="自定义ID标识符" class="目标类文件的路径名和包名"></bean>
列如:
<bean id="springDao" class="cn.shcool.dao.impl.DaoImplTwo"></bean>
步骤二:创建反转对象 ApplicationContext
固定格式:ApplicationContext 自定义ApplicationContext对象名 = new ClassPathXmlApplicationContext("applicationContext.xml");
步骤三:根据要反转的目标类名和其绑定的ID,来将其实例化
注意:如果你要反转的是一个实现类,那么推荐左侧为该实现类的接口,Bean配置中的id指定为class则指定为该实现类
格式:该实现类的接口类名 自定义反转实例化对象名 = (该实现类的接口类名) 自定义ApplicationContext对象名.getBean("配置文件中的id");
列如:
Dao d = (Dao) ac.getBean("springDao");
步骤四:调用实例化被反转后的实例化对象
格式:自定义反转实例化对象名.方法名();
列如:
d.run();
依赖注入
概念
用于解决问题,问题如下:
解决在多个Bean配置标签下,被创建了多个对象的冲突.
通过Set方式进行注入
①在UserServiceImpl中添加setUserDao方法
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
②配置Spring容器调用set方法进行注入
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<!-- 使用setUserDao方法,把userDao对象,注入userService中 -->
<property name="userDao" ref="userDao"/>
</bean>
通过构造方法进行注入
①在类中提供有参构造
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
②配置Spring容器调用有参构造时进行注入
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<!-- 使用构造方法,把userDao对象,注入userService中 -->
<constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
Bean依赖注入的数据类型
注入类型分类
Spring的依赖注入(也就是给成员变量赋值),可以分为三种类型。
1. 普通数据类型
2. 引用数据类型
3. 集合数据类型
这三种类型均可以使用“set方法赋值”,也可以使用“构造方法赋值”,以下以“set方法赋值”为例,进行演示。
普通数据类型的注入
public class UserDaoImpl implements UserDao {
private String company;
private int age;
public void setCompany(String company) {
this.company = company;
}
public void setAge(int age) {
this.age = age;
}
public void save() {
System.out.println(company + "===" +age);
}
}
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
<property name="company" value="传智播客"></property>
<property name="age" value="15"></property>
</bean>
引用数据类型的注入
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void save() {
userDao.save();
}
}
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
<bean id="userService" class="com.itheima.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
List的注入
public class UserDaoImpl implements UserDao {
private List<String> strList;
public void setStrList(List<String> strList) {
this.strList = strList;
}
public void save() {
System.out.println(strList);
System.out.println("UserDao save method running....");
}
}
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
<property name="strList">
<list>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</list>
</property>
</bean>
List的注入
其中’User’为自定义对象,比如也可以是Student对象。
public class UserDaoImpl implements UserDao {
private List<User> userList;
public void setUserList(List<User> userList) {
this.userList = userList;
}
public void save() {
System.out.println(userList);
System.out.println("UserDao save method running....");
}
}
<bean id="u1" class="com.itheima.domain.User"/>
<bean id="u2" class="com.itheima.domain.User"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
<property name="userList">
<list>
<bean class="com.itheima.domain.User"/>
<bean class="com.itheima.domain.User"/>
<ref bean="u1"/>
<ref bean="u2"/>
</list>
</property>
</bean>
Map<String,User> 的注入
public class UserDaoImpl implements UserDao {
private Map<String,User> userMap;
public void setUserMap(Map<String, User> userMap) {
this.userMap = userMap;
}
public void save() {
System.out.println(userMap);
System.out.println("UserDao save method running....");
}
}
<bean id="u1" class="com.itheima.domain.User"/>
<bean id="u2" class="com.itheima.domain.User"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
<property name="userMap">
<map>
<entry key="user1" value-ref="u1"/>
<entry key="user2" value-ref="u2"/>
</map>
</property>
</bean>
Properties的注入
public class UserDaoImpl implements UserDao {
private Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
}
public void save() {
System.out.println(properties);
System.out.println("UserDao save method running....");
}
}
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl">
<property name="properties">
<props>
<prop key="p1">aaa</prop>
<prop key="p2">bbb</prop>
<prop key="p3">ccc</prop>
</props>
</property>
</bean>
上一篇: 求任意两天的日期查差(两种方法)
下一篇: Java的常用输入输出语句