2a Spring搭建.txt
UP 返回
1.下载
访问 https://spring.io/projects ,选择spring framework ,下载最新版本
本地 F:\BaiduNetdiskDownload\2019年4月黑马程序员教程\01-黑马IDEA版本Java基础+就业课程\Java开发工具\jar包\spring 提供了3.2和4.2两个版本的spring,文件夹中RELEASE-dist为spring核心包,-docs为参考文档,-dependencies为相关依赖
2.spring的核心jar包
spring-core-3.2.2.RELEASE.jar 包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心。
spring-beans-3.2.2.RELEASE.jar 所有应用都要用到的,它包含访问配置文件、创建和管理bean,以及进行Inversion of Control(IoC) / Dependency Injection(DI)操作相关的所有类
spring-context-3.2.2.RELEASE.jar Spring提供在基础IoC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等。
spring-expression-3.2.2.RELEASE.jar Spring表达式语言
com.springsource.org.apache.commons.logging-1.1.1.jar 第三方的主要用于处理日志(需要依赖,在dependencies压缩包中)
3.搭建项目
3.1 创建项
设置文件夹,本地是D:\EnvironmentExtends\spring,将上面必须的几个jar包复制进去(选择class文件对应的jar,不用导入源码)
IDEA新建项目,选择Spring,点击右侧spring,在下面点击Use Library,点击create,选择刚才上面复制的路径下的几个包,确定
后面设置一下项目名称和位置即可
3.2 配置xml
在src下创建beans.xml,xml文件有两种约束,.dtd和.xsd
打开文件file:///F:/BaiduNetdiskDownload/2019%E5%B9%B44%E6%9C%88%E9%BB%91%E9%A9%AC%E7%A8%8B%E5%BA%8F%E5%91%98%E6%95%99%E7%A8%8B/01-%E9%BB%91%E9%A9%ACIDEA%E7%89%88%E6%9C%ACJava%E5%9F%BA%E7%A1%80+%E5%B0%B1%E4%B8%9A%E8%AF%BE%E7%A8%8B/Java%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/jar%E5%8C%85/spring/spring-framework-3.2.0.RC2-docs/reference/html/xsd-config.html
复制其中的约束(这里使用的是.xsd)到xml中,再配置自己的bean,参:D:\ProjectCodes\IDEA2017\spring-test-20191006\src\beans.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">
<!-- 上述的配置文件可以帮助我们在编辑xml文件时给出提示,需要联网。如果没有网络,可以事先访问该网址将文件下载到本地,再配置其位置即可 -->
<!-- bean definitions here -->
<bean id="userService" class="com.cn.service.UserServiceImpl"> <!-- spring通过反射来自动创建对象 -->
<property name="name" value="小米"></property> <!-- 依赖注入,会自动将值赋值给变量 -->
</bean>
</beans>
3.3 使用对象
public interface UserService {
public void add();
}
public class UserServiceImpl implements UserService {
private String name;
@Override
public void add() {
System.out.println("创建用户:"+name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
以前使用Service的方式,需要自己创建
UserService usr=new UserServiceImpl();
usr.add();
现在使用只需从容器中获取
//1.加载beans.xml这个spring配置文件,内部就会创建对象
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");//类路径,指的就是classes路径,打包以后src下的文件都会在这个文件夹内,故表示的路径和src同级(即路径从src之后开始写,如果放在src/com/cn/下就写/com/cn/beans.xml)
//2.从spring容器获取对象
UserServiceImpl usr=(UserServiceImpl) context.getBean("userService");
//只要从容器中取出对象,取出的都是同一个,可以取出两个打印一下看看就可以了
usr.add();
4.控制反转:IOC Inverse of Control
依赖注入:DI Dependency Injection
5.Spring容器加载的方式
5.1 ClassPathXmlApplicationContext
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
5.2 通过文件系统路径获得配置文件
ApplicationContext context=new FileSystemXmlApplicationContext("D:\ProjectCodes\IDEA2017\spring-test-20191006\src\beans.xml"); //即采用绝对路径
5.3 使用BeanFactory
BeanFactory factory=new XmlBeanFactory(new FileSystemResource("D:\\ProjectCodes\\IDEA2017\\spring-test-20191006\\src\\beans.xml")); //该方法已过时
factory.getBean()
6.BeanFactory和ApplicationContext对比
BeanFactory采取延迟加载,第一次getBean时才会初始化Bean
ApplicationContext采取即时加载,只要加载了ClassPathXmlApplicationContext就已经创建对象了。
ApplicationContext是对BeanFactory的扩展,提供了更多功能:国际化处理,事件传递,Bean自动装配,各种不同应用层的Context实现
7.装配bean的三种方式(就是指在xml中写一个bean标签)
7.1 new实现类
<bean id="userService" class="com.cn.service.UserServiceImpl"></bean>
7.2 通过静态工厂方法
首先创建工厂类,静态方法返回所需的bean
public class UserServiceFactory {
public static UserServiceImpl createUserService(){
return new UserServiceImpl();
}
}
xml中添加:
<bean id="userService2" class="com.cn.service.UserServiceFactory" factory-method="createUserService"></bean>
使用方法:
UserService usr3=(UserService) context.getBean("userService2");
usr3.add();
会报IllegalArgumentException的异常,因为spring版本过低,3.0版本的spring需要jdk为1.7才可以。spring版本高的话就不会抛出异常了
7.3 通过实例工厂方法
xml中添加:
<bean id="factory" class="com.cn.service.UserServiceFactory"></bean>
<bean id="userService3" factory-bean="factory" factory-method="createUserService"></bean>
使用:
UserService usr3=(UserService) context.getBean("userService3");
8.bean的作用域(重点前两个掌握)和生命周期
singleton 在sprint IoC容器中仅存在一个Bean实例。此为默认值
prototype 每次从容器中调用Bean时,都返回一个新的实例。即getBean()时相当于new Bean()
request 每次http请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
session 同一个HTTP Session共享一个Bean,不同Session使用不同Bean,仅适用于WebApplicationContext环境
globalSession 一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext环境
xml中的写法:
<bean id="userService" class="com.cn.service.UserServiceImpl" scope="singleton"></bean>
生命周期图解释(了解)
1.instantiate bean对象实例化
2.populate properties 封装属性
3.如果Bean实现BeanNameAware 执行 setBeanName
4.如果Bean实现BeanFactoryAware 执行setBeanFactory ,获取Spring容器
5.如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean 执行 afterPropertiesSet
7.调用<bean init-method="init"> 指定初始化方法 init
8.如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization
执行业务处理
9.如果Bean实现 DisposableBean 执行 destroy
10.调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy
9.给对象属性赋值的方式
9.1 构造方法注入(下面写参数的标签要有相应的构造方法。参数不同对应不同的构造方法)
public class Student {
private String name;
private int age;
private String password;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
}
<bean id="stu" class="com.cn.model.Student">
<constructor-arg name="name" value="wiw"></constructor-arg>
<constructor-arg name="age" value="20"></constructor-arg>
</bean>
9.2 通过参数索引加类型给构造方法赋值(也要有对应的构造方法)
<bean id="stu" class="com.cn.model.Student">
<constructor-arg index="0" value="wiw" type="java.lang.String"></constructor-arg>
<constructor-arg index="1" value="20" type="java.lang.Integer"></constructor-arg>
</bean>
9.3 通过属性的set方法注入(参3.2中的写法)
9.4 通过p命名空间注入(了解)
在xml约束里添加命名空间(p标签):xmlns:p="http://www.springframework.org/schema/p"
<bean id="stu" class="com.cn.model.Student" p:username="wiw" p:age="15"></bean> (报错,原因未知)
10 spring表达式
10.1 value可以使用的值(<property name="name" value="小米"></property>)
#{123}、#{'jack'} : 数字、字符串
#{beanId} :另一个bean引用
#{beanId.propName} :操作数据
#{beanId.toString()} :执行方法
#{T(类).字段|方法} :静态方法或字段
public class Address {
private String addr;
}
public class Customer {
private String name;
private String sex="男";
private double pi;
private Address addr;
}
<bean id="addr" class="com.cn.model.Address">
<property name="addr" value="hefei"></property> <!-- 被引用的bean -->
</bean>
<bean id="customer" class="com.cn.model.Customer">
<!--<property name="name" value="#{'haha'.toUpperCase()}"></property>--> <!-- 调用方法 -->
<property name="name" value="#{addr.addr}"></property> <!-- 引用别的bean的变量-->
<property name="pi" value="#{T(java.lang.Math).PI}"></property> <!-- 引用类中的字段-->
<!--<property name="addr" value="#{addr}"></property>--> <!-- 对其他bean的引用-->
<property name="addr" ref="addr"></property> <!-- 对其他bean的引用也可以用ref标签-->
</bean>
11.集合注入
集合的注入都是给<property>添加子标签
数组:<array>
List:<list>
Set:<set>
Map:<map> ,map存放k/v 键值对,使用<entry>描述
Properties:<props> <prop key=""></prop> 【】
普通数据:<value>
引用数据:<ref>
public class Programmer {
private List<String> carList;
private Map<String,String> infos;
private Properties mysqlInfos;
}
<bean id="programmer" class="com.cn.model.Programmer">
<property name="carList">
<list> <!-- 数组,Set类比该写法-->
<value>Audi</value>
<value>Menz</value>
<value>BWM</value>
</list>
</property>
<property name="infos">
<map>
<entry key="name" value="22"></entry>
<entry key="age" value="44"></entry>
<entry key="ip" value="127.0.0.1"></entry>
</map>
</property>
<property name="mysqlInfos">
<props>
<prop key="url">mysql:jdbc://localhost:3306/dbname</prop>
<prop key="user">root</prop>
<prop key="password">123654</prop>
</props>
</property>
</bean>
DOWN 返回