Spring基础
Spring是一个轻量级开源框架,以IoC(控制反转)和AOP(面向切面编程)为内核,基于JavaBean来完成以前只能由EJB完成的工作。
主要学习Spring的以下几个核心功能
- IoC(控制反转):即把对象的创建交给Spring去执行(利用xml文件配置创建+IoC 容器创建对象)
- AOP(面向切面编程):有效减少系统重复代码
- SpringJDBC
- Spring 事务处理
Spring IoC
1. 首先引入jar包
IoC必须引入四个包+日志包
- spring-core
- spring-beans
- spring-context
- spring-expression
- commons.logging
2. Spring对象的创建
Spring提供了两种IoC容器BeanFactory和ApplicationContext,常用ApplicationContext。
配置文件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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 要创建的所有对象都配置在这里 -->
<!--
scope="singleton" 默认值 单例 在容器初始化之前就已经创建了容器 适用于service/dao/工具类
scope="prototype" 多例 用到时才创建对象 适用于Action对象
-->
<!-- 1.一般对象无参创建配置,默认就使用无参构造器(scope:单例/多例模式;默认单例模式,在IOC容器初始化时创建;多例模式在调用返回对象时创建) -->
<bean id="user" class="com.wsk.spring_hello.User" scope="singleton" lazy-init="false" init-method="init_user" destroy-method="destroy_user"></bean>
<!-- 2.带参数对象创建配置 -->
<bean id="user1" class="com.wsk.spring_hello.User">
<!-- 给定两个参数 (基本类型可以直接写,其他引用类型要写类全称)-->
<constructor-arg type="int" value="100"></constructor-arg>
<constructor-arg type="java.lang.String" value="Jack"></constructor-arg>
</bean>
<!-- 通过引用赋值 -->
<bean id="str" class="java.lang.String">
<constructor-arg value="Jeck"></constructor-arg>
</bean>
<bean id="user2" class="com.wsk.spring_hello.User">
<!-- 给定两个参数 (基本类型可以直接写,其他引用类型要写类全称)-->
<constructor-arg type="int" value="100"></constructor-arg>
<constructor-arg type="java.lang.String" ref="str"></constructor-arg>
</bean>
<!-- 工厂方法创建实例对象 -->
<!-- 1.先创建工厂类 -->
<bean id="factory" class="com.wsk.spring_hello.Factory"></bean>
<!-- 创建User对象,用factory方法实例方法 -->
<bean id="user3" factory-bean="factory" factory-method="getUser"></bean>
<!-- 静态方法创建 -->
<bean id="user4" class="com.wsk.spring_hello.Factory" factory-method="getUserStatic"></bean>
</beans>
对象类User.java
package com.wsk.spring_hello;
public class User {
private int id;
private String name;
public User() {
System.out.println("User无参对象被创建");
}
public User(int id,String name ) {
System.out.println("User有参对象被创建");
this.id=id;
this.name=name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void init_user(){
System.out.println("对象初始化");
}
public void destroy_user(){
System.out.println("对象销毁");
}
}
工厂类Factory.java
package com.wsk.spring_hello;
public class Factory {
// 普通工厂方法,要通过创建工厂类实例调用方法实现实例化对象
public User getUser(){
System.out.println("工厂方法创建");
return new User();
}
// 静态工厂方法,直接使用类名.方法名返回创建对象
public static User getUserStatic(){
System.out.println("静态工厂方法创建");
return new User();
}
}
调用类App.java
package com.wsk.spring_hello;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
public class App {
/**
* 通过工厂类得到IOC容器创建对象
*/
@Test
public void testIOC(){
// 把对象创建交给IOC容器
Resource rs = new ClassPathResource("com/wsk/spring_hello/applicationContext.xml");
// 创建对象Bean工厂 IOC容器=工厂类+applicationContext.xml
BeanFactory factory = new XmlBeanFactory(rs);
// 得到容器创建的对象
User user = (User) factory.getBean("user");
System.out.println(user.getId());
}
/**
* 直接得到IOC容器创建对象
* 默认是单例的,scope="singleton" 默认值 单例 在容器初始化之前就已经创建了对象 适用于service/dao/工具类
* scope="prototype" 多例 用到时才创建对象 适用于Action对象
* 是否延迟加载
* lazy-init="false" 默认是false不延迟创建,再启动时创建对象
* lazy-init="true" 延迟创建,在使用时创建对象
* 创建后,初始化和销毁
* init-method="" IOC容器创建时执行的方法
* destroy-method="" IOC 容器销毁时执行的方法
*
*/
@Test
public void testAC(){
// 得到IOC容器对象
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("com/wsk/spring_hello/applicationContext.xml");
System.out.println("----IOC容器创建-----");
// 从容器中获取bean
User user = (User) ac.getBean("user");
User user1 = (User) ac.getBean("user");
System.out.println(user);
System.out.println(user1);
ac.destroy();
}
@Test
public void test(){
// 得到IOC容器对象 【用实现类,因为要调用销毁的方法】
ApplicationContext ac = new ClassPathXmlApplicationContext("com/wsk/spring_hello/applicationContext.xml");
System.out.println("-----容器创建-----");
// 从容器中获取bean
User user = (User) ac.getBean("user");
User user1 = (User) ac.getBean("user1");
User user2 = (User) ac.getBean("user2");
System.out.println(user);
System.out.println(user1);
System.out.println(user2.getName());
}
@Test
public void testFactory(){
// 得到IOC容器对象 【用实现类,因为要调用销毁的方法】
ApplicationContext ac = new ClassPathXmlApplicationContext("com/wsk/spring_hello/applicationContext.xml");
System.out.println("-----容器创建-----");
// 从容器中获取bean
User user = (User) ac.getBean("user4");
System.out.println(user);
}
}
3. Spring依赖注入
依赖注入就是把对象所需要的属性值注入到对象中,一共有三种实现方式
- setter注入:每个注入属性必须有一个和名字对应的set方法
- 构造方法注入
- 接口注入:spring容器不支持这种注入
构造方法注入
<!-- 通过引用赋值 -->
<bean id="str" class="java.lang.String">
<constructor-arg value="Jeck"></constructor-arg>
</bean>
<bean id="user2" class="com.wsk.spring_hello.User">
<!-- 给定两个参数 (基本类型可以直接写,其他引用类型要写类全称)-->
<constructor-arg type="int" value="100"></constructor-arg>
<constructor-arg type="java.lang.String" ref="str"></constructor-arg>
</bean>
setter方法注入
实体类
public class UserDao {
// 注意使用set注入,不用创建new User() 只需提供set方法就行
private User user;
public void setUser(User user) {
this.user = user;
}
public void save() {
System.out.println("UserDao.save()");
System.out.println("UserId="+user.getId()+" UserName="+user.getName());
}
}
配置文件
<bean id="user" class="com.wsk.sprin2.User">
<property name="id" value="101"></property>
<property name="name" value="Jeck"></property>
</bean>
<bean id="userDao" class="com.wsk.sprin2.UserDao">
<property name="user" ref="user"></property>
</bean>
4. 基于p名称空间的装配
private ApplicationContext ac = new ClassPathXmlApplicationContext("com/wsk/sprin2/bean_p.xml");
@Test
public void testApp(){
UserService userService=(UserService) ac.getBean("userService");
userService.service();
System.out.println(userService);
}
配置文件
<bean id="user" class="com.wsk.sprin2.User" p:id="101" p:name="Jeck"></bean>
<bean id="userDao" class="com.wsk.sprin2.UserDao" p:user-ref="user"></bean>
<bean id="userService" class="com.wsk.sprin2.UserService" p:userDao-ref="userDao"></bean>
5. 基于注解的装配
修饰类的注解有:
- @Component
- @Respository
- @Service
- @Constroller
修饰注入属性的注解
@Resource 可以指定属性值进行匹配装配,属性值有name type
示例代码
// 这行带代码相当于bean.xml[<bean id="userDao" class="..."/>]
//@Component // 将注解修饰对象加入到IOC容器中,默认加入的id就是类名第一个字母小写
@Repository // 在持久层可以选用这个注解,区分每层
public class UserDao {
@Resource
private User user1; // 根据这个字段类型去IOC容器中寻找(以前版本是根据名称字段去找id)
public void save(){
System.out.println("UserDao.save()");
System.out.println(user1.getName());
}
}
需要在配置文件中开启注解扫描
<context:component-scan base-package="com.wsk.spring3"></context:component-scan>
6. 自动装配
配置元素中的autowire属性