1.什么是spring
简单来说,Spring 是一个分层的 JavaSE/EEfull-stack(一站式) 轻量级 开源框架。
2.spring的作用
2.1 方便解耦,简化开发
Spring 就是一个大工厂,可以将所有对象创建和依赖关系维护,交给 Spring 管理
2.2 AOP 编程的支持
Spring 提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
2.3 声明式事务的支持
只需要通过配置就可以完成对事务的管理,而无需手动编程
2.4 方便程序的测试
Spring 对 Junit4 支持,可以通过注解方便的测试 Spring 程序
2.5 方便集成各种优秀框架
Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz 等)的直接支持
2.6 降低 JavaEE API 的使用难度
Spring 对 JavaEE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等),都提供了封装,使这些 API 应用难度大大降低
3.spring的使用
3.1 导包
如果是之前使用eclipse进行开发的同学,使用idea应该会觉得非常爽,非常方便。首先创建工程的时候,只需要勾选上需要依赖的框架,那么idea就会为你下载最新的jar包,不用你再进行手动的导包了。
3.2 配置spring
先看目录结构1.创建User类
public class User {
String name;
Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
2.书写配置文件
2.1 配置文件默认放到src路径下(无强制规定,程序员都放src下),文件名applicationContext.xml(无强制规定,程序员都这么起),自己看着办好伐。
2.2 这里,在idea下,直接就可以进行配置文件的书写,无需像在eclipse里面一样,还要引入约束,相信用过eclipse的同学会有感触。
这里直接将三种创建方式都放上来了,我们只介绍创建方式1,方式2和3并不常用,不详细介绍了。
<?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">
<!--将user交给spring容器管理-->
<!-- 创建方式1:空参构造创建 -->
<!-- name:别名 class:类路径 scope:singleton 单例模式 prototype多例模式-->
<bean name="user" class="bean.User" scope="singleton"></bean>
<!-- 创建方式2:静态工厂创建(不常用)
调用UserFactory的createUser方法创建名为user2的对象.放入容器
-->
<bean name="user2"
class="bean.UserFactory"
factory-method="createUser" ></bean>
<!-- 创建方式3:实例工厂创建(不常用)
调用UserFactory对象的createUser2方法创建名为user3的对象.放入容器
-->
<bean name="user3"
factory-bean="userFactory"
factory-method="createUser2" ></bean>
<bean name="userFactory"
class="bean.UserFactory" ></bean>
</beans>
4.测试
public class Test01 {
@Test
public void testFunc() {
// 使用spring来创建对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过 applicationContext 获取对象
User user = (User) applicationContext.getBean("user");
User user2 = (User) applicationContext.getBean("user");
System.out.println(user);
System.out.println(user == user2);
}
}
5. 方式2和方式3作为了解
public class UserFactory {
public static User createUser(){
System.out.println("静态工厂创建User");
return new User();
}
public User createUser2(){
System.out.println("实例工厂创建User");
return new User();
}
}
public class Test01 {
@Test
public void testFunc() {
// 使用spring来创建对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过 applicationContext 获取对象
User user2 = (User) applicationContext.getBean("user2");
User user3 = (User) applicationContext.getBean("user3");
System.out.println(user2);
System.out.println(user3);
}
}
4. 生命周期
41. 配置
<!-- 创建方式1:空参构造创建 -->
<bean name="user" class="bean.User" scope="singleton"
init-method="init" destroy-method="destroy"></bean>
42. 在user中实现方法
public void init() {
System.out.println("初始化方法调用");
}
public void destroy() {
System.out.println("销毁方法调用");
}
43. 测试
@Test
public void testFun2() {
// 使用spring来创建对象
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// 通过 applicationContext 获取对象
User user = (User) applicationContext.getBean("user");
System.out.println(user);
applicationContext.close();
}
初始化方法调用
bean.User@4f063c0a
Jul 30, 2018 10:38:56 AM org.springframework.context.support.ClassPathXmlApplicationContext doClose
销毁方法调用
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@4fccd51b: startup date [Mon Jul 30 10:38:56 CST 2018]; root of context hierarchy
Process finished with exit code 0
5.模块化配置
可以通过引入其他的配置文件,用不同的配置文件专门配置某些类
6. 属性注入
6.1 set方法注入
1.创建dog类
public class Dog {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- 在User中添加Dog类型的属性
public class User {
private String name;
private Integer age;
private Dog dog;
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
-
书写配置文件
4.打印结果
6.2 构造方法注入
1.在User中添加构造方法
public User(String name, Dog dog) {
this.name = name;
this.dog = dog;
}
2.书写配置文件
<!--构造方法注入-->
<bean name="user2" class="bean.User" scope="singleton">
<constructor-arg name="name" value="张三"/>
<constructor-arg name="dog" ref="dog"/>
</bean>
<bean name="dog" class="bean.Dog" scope="singleton">
<property name="name" value="旺财"/>
<property name="age" value="3"/>
</bean>
添加:index指定构造参数顺序:
如果User中有两个构造方法,并且属性相同,只是顺序不同
public User(String name, Dog dog) {
this.name = name;
this.dog = dog;
}
public User(Dog dog,String name) {
this.name = name;
this.dog = dog;
}
这时候需要在配置文件中,通过index指定参数的顺序
<!--构造方法注入-->
<!--constructor-arg:构造参数-->
<bean name="user2" class="bean.User" scope="singleton">
<constructor-arg name="name" value="张三" index="0"/>
<constructor-arg name="dog" ref="dog" index="1"/>
</bean>
<bean name="dog" class="bean.Dog" scope="singleton">
<property name="name" value="旺财"/>
<property name="age" value="3"/>
</bean>
添加:type指定构造参数的参数类型:
如果User中有两个构造方法,参数名相同,只是类型不同
public User(String name, Dog dog) {
this.name = name;
this.dog = dog;
}
public User(Integer name, Dog dog) {
this.name = name + "";
this.dog = dog;
}
这时候需要通过在配置文件中,指定参数的类型
<!--构造方法注入-->
<!--constructor-arg:构造参数-->
<!-- name属性: 构造函数的参数名 -->
<!-- index属性: 构造函数的参数索引 -->
<!-- type属性: 构造函数的参数类型-->
<bean name="user2" class="bean.User" scope="singleton">
<constructor-arg name="name" value="89757" index="0" type="java.lang.Integer"/>
<constructor-arg name="dog" ref="dog" index="1"/>
</bean>
<bean name="dog" class="bean.Dog" scope="singleton">
<property name="name" value="旺财"/>
<property name="age" value="3"/>
</bean>
6.3 p名称空间注入
1.在配置文件中导入p名称空间
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
2.书写要配置的对象
<bean name="user3" class="bean.User" p:name="李四" p:age="20" p:dog-ref="dog">
</bean>
6.4 spel表达式注入
<bean name="user4" class="bean.User" >
<!--name:赋值user的name age:赋值user2的age-->
<property name="name" value="#{user.name}"/>
<property name="age" value="#{user2.age}"/>
<!--spel表达式不支持引用类型-->
<property name="dog" ref="dog"/>
</bean>
7.复杂类型注入
先创建一个类,包含各种array、list、map
public class CollectionBean {
private Object[] arr;
private List list;
private Map map;
public Object[] getArr() {
return arr;
}
public void setArr(Object[] arr) {
this.arr = arr;
}
public List getList() {
return list;
}
public void setList(List list) {
this.list = list;
}
public Map getMap() {
return map;
}
public void setMap(Map map) {
this.map = map;
}
@Override
public String toString() {
return "CollectionBean{" +
"arr=" + Arrays.toString(arr) +
", list=" + list +
", map=" + map +
'}';
}
7.1 array数组注入
1.单个元素注入
<bean name="collectionBean" class="bean.CollectionBean">
<!--如果数组中只准备注入一个值,那么可以直接使用value|ref-->
<property name="arr" value="tom"/>
</bean>
2.多个元素注入
<bean name="collectionBean" class="bean.CollectionBean">
<!--如果数组中只准备注入一个值,那么可以直接使用value|ref-->
<!--<property name="arr" value="tom"/>-->
<property name="arr">
<array>
<value>旺财1号</value>
<value>旺财2号</value>
<ref bean="user4"/>
</array>
</property>
</bean>
7.2 list注入
和array注入类似
1.单个元素注入
<bean name="collectionBean" class="bean.CollectionBean">
<!--如果数组中只准备注入一个值,那么可以直接使用value|ref-->
<property name="list" value="tom"/>
</bean>
2.多个元素注入
<bean name="collectionBean" class="bean.CollectionBean">
<!--<property name="list" value="tom"/>-->
<property name="list">
<list>
<value>tom1</value>
<value>tom2</value>
<ref bean="user"/>
</list>
</property>
</bean>
7.3 map注入
<bean name="collectionBean" class="bean.CollectionBean">
<property name="map">
<map>
<entry key="url" value="jdbc:mysql:///crm"/>
<entry key="dog" value-ref="dog"/>
<entry key-ref="user" value-ref="dog"/>
</map>
</property>
</bean>
7.4 properties注入
<bean name="collectionBean" class="bean.CollectionBean">
<property name="properties">
<props>
<prop key="driverClass">com.jdbc.mysql.Driver</prop>
<prop key="userName">root</prop>
<prop key="password">123456</prop>
</props>
</property>
</bean>
8. 设置spring生命周期,绑定到Application域
8.1 配置spring
<!--让spring容器岁项目的创建而创建,项目关闭而销毁-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--指定加载spring配置文件的位置-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
8.2 从servletContext中获取applicationContext容器
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.apache.struts2.ServletActionContext;
import javax.servlet.ServletContext;
public class Test01 {
@Test
public void testFunc1() {
ServletContext servletContext = ServletActionContext.getServletContext();
WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
User user = (User) webApplicationContext.getBean("user");
}
}