Spring快速入门
编写流程
- 下载Spring开发包
- 导入Spring的jar包
- 配置Spring的核心xml文件
- 在程序中读取Spring的配置文件来获取Bean[Bean其实就是一个new好的对象]
Spring的核心jar包
- spring-core-xxx.RELEASE.jar
- 包含Spring框架基本的核心工具类,Spring其他组件都要使用到这个包里的类,是其他组件的基本核心。
- spring-beans-xxx.RELEASE.jar
- 所有应用都要用到的,它包含访问配置文件、创建和管理bean,以及进行Inverse of Control(IOC)/Dependency Injection(DI)操作相关的所有类。
- spring-context-xxx.RELEASE.jar
- spring提供在基础IOC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等。
- spring-expression-xxx.RELEASE.jar
- spring表达式语言
- com.springsource.org.apache.commons.logging-xxx.jar
- 第三方的主要用于处理日志
Spring中beans.xml文件的建立和使用
- 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"> <!-- bean definitions here --></beans>
- beans.xml中配置一个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">
<!--配置一个bean[对象]-->
<bean id="userService" class="com.cyh.service.IUserServiceImpl"></bean></beans>
- 在测试类中加载beans.xml
package com.cyh.test;
import com.cyh.service.IUserService;
import com.cyh.service.IUserServiceImpl;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Lesson02 {
//现在使用UserService方式从spring容器中获取
@Test
public void test2(){
//1.加载beans.xml这个spring配置文件
ApplicationContext context =
new ClassPathXmlApplicationContext("com/cyh/beans.xml");
//2.从spring容器(context)获取IUserService对象
IUserService userService = (IUserServiceImpl)context.getBean("userService");
//3.调用
userService.add();
}
}
//注意:通过getBean得到的对象,无论创建几个,都是一个对象!
总结【IoC】
IoC Inverse of Control反转控制的概念,就是将原本在程序中手动创建UserService对象的控制权,交由Spring框架管理,简单说,就是创建UserService对象的控制权被反转到了Spring框架。
DI解释与使用
-
Dependency Injection依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件。
-
在UserService中提供一个get/set的name方法,在beans.xml中通过property去注入
-
在Userservice中提供get/set的name方法
package com.cyh.service; public class IUserServiceImpl implements IUserService{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void add() { System.out.println("创建用户......"+name); } }
-
在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"> <!--配置一个bean[对象]--> <bean id="userService" class="com.cyh.service.IUserServiceImpl"> <!--依赖注入数据--> <property name="name" value="caiyuhao"></property> </bean> </beans>
-
Spring容器创建的三种方式
-
第一种:ClassPathXmlApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("com/cyh/beans.xml"); IUserService userService = (IUserServiceImpl)context.getBean("userService");
-
第二种:文件系统路径获取跑配置文件
//1.加载beans.xml这个spring配置文件 ApplicationContext context = new FileSystemXmlApplicationContext( "F:\\Idea_Project\\spring\\demo3\\src\\com\\cyh\\beans.xml"); //2.从spring容器(context)获取IUserService对象 IUserService userService = (IUserServiceImpl)context.getBean("userService");
-
第三种:使用BeanFactory(了解)
String path="F:\\Idea_Project\\spring\\demo3\\src\\com\\cyh\\beans.xml"; BeanFactory factory = new XmlBeanFactory(new FileSystemResource(path)); //2.从spring容器(context)获取IUserService对象 IUserService userService = (IUserServiceImpl)factory.getBean("userService");
-
spring内部创建对象的原理:
1.解析xml文件,获取类名,id,属性
2.通过反射,用类型创建对象
3.给创建的对象赋值
注:spring的配置文件通常放在src目录下
BeanFactory和ApplicationContext对比
- BeanFactory采取延迟加载,第一次getBean时才会初始化bean
- ApplicationContext是及时加载,对BeanFactory扩展,提供了更多功能
- 国际化处理
- 事件传递
- Bean自动装配
- 各种不同应用层的Context实现
装配Bean的三种方式讲解
-
第一种:new实现类
<!--配置一个bean[对象]--> <bean id="userService1" class="com.cyh.service.IUserServiceImpl"></bean>
-
第二种:通过静态工厂方法
- beans.xml配置
<bean id="userService2" class="com.cyh.service.IUserServiceFactory1" factory-method="createUserService"></bean> 注意:使用此工厂方法需要JDK的版本为:1.7。
- 工厂类代码
public class IUserServiceFactory1 { public static IUserService createUserService(){ return new IUserServiceImpl(); } }
-
第三种:通过实例工厂方法
- 工厂类代码
public class IUserServiceFactory { public IUserService createUserService(){ return new IUserServiceImpl(); } }
- beans.xml配置代码
<bean id="factory" class="com.cyh.service.IUserServiceFactory"></bean> <bean id="userService3" factory-bean="factory" factorymethod="createUserService"></bean>
- 测试类里面的代码
@Test public void test5(){ ApplicationContext context = new ClassPathXmlApplicationContext("com/cyh/bean3.xml"); IUserService userService2 = (IUserService)context.getBean("userService3"); userService2.add(); }
Bean的作用域
仅需要掌握前两个
类别 | 说明 |
---|---|
singleton | 在Spring IoC容器中仅存在一个Bean实例,Bean以单例方式存在,默认值。 |
prototype | 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean()。(可以理解成多例) |
request | 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境。 |
session | 同一个HTTP Session共享一个Bean,不同Session使用不同Bean,仅适用于WebApplicationContext环境。 |
globalSession | 一般用于Portlet应用环境,该作用域仅适用于WebApplicationContext环境。 |
- 演示
<?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 id="userService" class="com.cyh.service.IUserServiceImpl" scope="singleton"></bean>
<!--多例模式,每次创建的都是不同对象-->
<bean id="userService" class="com.cyh.service.IUserServiceImpl" scope="prototype"></bean>
</beans>
Bean的生命周期(了解)
-
举例演示
-
创建一个基类User.java
package com.cyh.model; import org.springframework.beans.BeansException; import org.springframework.beans.factory.*; public class User implements BeanNameAware , BeanFactoryAware , InitializingBean , DisposableBean { private String username; private String password; public User() { System.out.println("1.实例化"); } public String getUsername() { return username; } public void setUsername(String username) { System.out.println("2.赋值属性:"+username); this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "username='" + username + '\'' + ", password='" + password + '\'' + '}'; } @Override public void setBeanName(String s) { System.out.println("3.设置Bean的名字:"+s); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("4.Bean工厂:"+beanFactory); } @Override public void afterPropertiesSet() throws Exception { System.out.println("6.属性赋值完成..."); } public void myInit(){ System.out.println("7.自定义初始化方法..."); } @Override public void destroy() throws Exception { System.out.println("9.Bean对象被销毁..."); } public void myDestroy(){ System.out.println("10.自定义的销毁方法..."); } }
-
新建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"> <bean id="user" class="com.cyh.model.User" init-method="myInit" destroy-method="myDestroy"> <property name="username" value="one"></property> <property name="password" value="two"></property> </bean> <!--配置bean处理器--> <bean id="beanProcess" class="com.cyh.model.MyBeanPostProcessor"></bean> </beans>
-
新建MyBeanPostProcessor.java
package com.cyh.model; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object o, String s) throws BeansException { //这边可以用于多个对象共同的事情处理 System.out.println("5.预处理:"+o+":"+s); return o; } @Override public Object postProcessAfterInitialization(Object o, String s) throws BeansException { System.out.println("8.后处理:"+o+":"+s); return o; } }
-
新建测试类测试Bean生命周期执行流程
package com.cyh.test; import com.cyh.model.User; import com.cyh.service.IUserService; import com.cyh.service.IUserServiceImpl; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import javax.jws.soap.SOAPBinding; import java.lang.reflect.InvocationTargetException; public class Lesson05 { @Test public void test1() { ApplicationContext context = new ClassPathXmlApplicationContext("com/cyh/beans5.xml"); User user = (User)context.getBean("user"); System.out.println(user); try { context.getClass().getMethod("close").invoke(context); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } }
-
依赖注入Bean属性(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"> <!--构造方法注入--> <bean id="stu" class="com.cyh.model.Student"> <constructor-arg name="username" value="cyh"></constructor-arg> <constructor-arg name="age" value="23"></constructor-arg> </bean> </beans>
-
通过索引加类型 给构造方法赋值
<?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 id="stu" class="com.cyh.model.Student"> <constructor-arg index="0" value="cyh" type="java.lang.String"> </constructor-arg> <constructor-arg index="1" value="23" type="int"></constructor-arg> </bean> </beans>
-
通过set方法往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"> <!--通过set方法往bean注入属性值--> <bean id="stu" class="com.cyh.model.Student"> <property name="username" value="cyh"></property> <property name="password" value="123"></property> <property name="age" value="23"></property> </bean> </beans>
-
通过p命名空间注入(了解)
-
需要在beans.xml文件中引入p标签的支持
xmlns:p="http://www.springframework.org/schema/p"
-
使用方法
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="stu" class="com.cyh.model.Student" <!--通过p命名空间注入--> p:username="zhangsan" p:password="123" p:age="21"> </bean> </beans>
-
SpEL表达式(了解)
Spring表达式
特点:
对进行统一编程,所有的内容都使用value
<property name="" value="#{表达式}">
表现形式 | 说明 |
---|---|
#{123} | 数字 |
#{‘jack’} | 字符串 |
#{beanId} | 另一个bean引用 |
#{beanId.propName} | 操作数据 |
#{beanId.toString()} | 执行方法 |
#{T(类).字段|方法} | 静态方法或字段 |
例子
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="address" class="com.cyh.model.Address">
<property name="name" value="南京市"></property>
</bean>
<bean id="customer" class="com.cyh.model.Customer">
<property name="name" value="#{'张三'}"></property>
<property name="sex" value="#{'男'}"></property>
<property name="pi" value="#{T(java.lang.Math).PI}"></property>
<!--通过ref指向对象的id-->
<property name="address" ref="address"></property>
<!--通过#{beanId}直接指向待调用beanId-->
<property name="address" value="#{address}"></property>
</bean>
</beans>
集合注入
集合注入都是给添加子标签
演示
-
创建模型类Programmer.java
package com.cyh.model; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; public class Programmer { private List<String> cars; private Set<String> pats; private Map<String,Integer> people; private Properties tx; private String[] array; public String[] getArray() { return array; } public void setArray(String[] array) { this.array = array; } public Properties getTx() { return tx; } public void setTx(Properties tx) { this.tx = tx; } public Map<String, Integer> getPeople() { return people; } public void setPeople(Map<String, Integer> people) { this.people = people; } public List<String> getCars() { return cars; } public void setCars(List<String> cars) { this.cars = cars; } public Set<String> getPats() { return pats; } public void setPats(Set<String> pats) { this.pats = pats; } @Override public String toString() { return "Programmer{" + "cars=" + cars + '}'; } }
-
创建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" 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"> <bean id="pro" class="com.cyh.model.Programmer"> <!--成员变量为List类型时--> <property name="cars"> <list> <value>丰田</value> <value>宝马</value> <value>大众</value> </list> </property> <!--成员变量为Set类型时--> <property name="pats"> <set> <value>猫</value> <value>狗</value> </set> </property> <!--成员变量为Map类型时--> <property name="people"> <map> <entry key="one" value="10"></entry> <entry key="two" value="20"></entry> </map> </property> <!--成员变量为Properties时--> <property name="tx"> <props> <prop key="url">mysql:jdbc://localhost:3306/db</prop> <prop key="user">root</prop> <prop key="password">123456</prop> </props> </property> <!--成员变量为数组类型时--> <property name="array"> <array> <value>123</value> <value>456</value> <value>789</value> </array> </property> </bean> </beans>
在测试类中测试即可。
注解注入
- 注解:就是一个类,使用@注解名称
- 开发中:使用注解 取代 xml配置文件
@Component注解的使用
注:web开发中,提供3个@Component注解衍生注解(功能一样)取代
语法 | 解释说明 |
---|---|
@Repository(“名称”) | dao层 |
@Service(“名称”) | service层 |
@Controller(“名称”) | web层 |
@Autowired | 自动根据类型注入 |
@Qualifier(“名称”) | 指定自动注入的id名称 |
@Resource(“名称”) | |
@PostConstruct | 自定义初始化 |
@PreDestroy | 自定义销毁 |
注意:默认情况下,spring是不开启注解功能的,需要在beans.xml文件中加上下面两行:
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
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"
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">
<!--开启注解-->
<context:annotation-config/>
<!--注解的位置-->
<!--com.cyh包下的所有类-->
<context:component-scan base-package="com.cyh"/>
</beans>
在IUserServiceImpl.java中添加注解@Component
package com.cyh.service;
import com.cyh.model.User;
import org.springframework.stereotype.Component;
//@Component 没有添加id则测试类中需要通过类名来获取实例对象
@Component("userService") //指定id名称的话测试类中可以通过id来获取实例对象
public class IUserServiceImpl implements IUserService{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void add() {
System.out.println("创建用户......"+name);
}
@Override
public void add(User user) {
System.out.println("添加用户"+user);
}
}
测试类代码如下:
package com.cyh.test;
import com.cyh.model.User;
import com.cyh.service.IUserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Lesson10 {
@Test
public void test1() {
ApplicationContext context = new ClassPathXmlApplicationContext("com/cyh/beans10.xml");
//如果@Component没配置id,则通过类型获取
//IUserService bean = (IUserService)context.getBean(IUserServiceImpl.class);
//如果@Component配置id,则通过id获取
IUserService bean = (IUserService)context.getBean("userService");
User user = new User();
user.setUsername("zhangsan");
bean.add(user);
}
}