Spring框架是一个开源的JavaEE应用程序
主要核心是IOC和AOP两大技术
Spring官网:spring.io
目前学习的是:Spring Framework
Dao层:
JDBC操作。对应框架:MyBatis
Service层:
Spring框架不是针对service层业务逻辑,service层没哟适合的框架
Controller层:
Servlet(接收请求,响应数据,地址配置,页面转发)
对应框架:Spring MVC
org.springframework
spring-context
6.2.1
package com.gtc.service;
public class UserService {
public void test(){
System.out.println("UserService Test...");
}
}
在Spring框架中,spring.xml
是Spring配置文件的标准格式,通常用于配置Spring的Bean,即对象的创建、初始化、依赖注入等。通过spring.xml
,我们可以定义Spring容器需要管理的所有对象及其属性和行为。
注意:这是Spring框架定义好的格式。
package com.gtc.test;
import com.gtc.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Starter01 {
public static void main(String[] args) {
// 得到Spring的上下文环境
ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml");
// 通过id属性值得到指定的bean对象 (传统方法需要自己new)
UserService userService = (UserService) ac.getBean("userService");
// 调用实例化好的javabean对象中的方法
userService.test();
}
}
new UserService()
的过程交给IOC去做了
手动实例化与外部引入
示例1:
public class UserService{ UserDao userDao = new UserDao(); }
示例2:
public class UserService{ private UserDao userDao; public UserService(UserDao userDao){ this.userDao = userDao; } }
对比发现:示例二中对于UserDao对象的创建并没有像示例一那样主动的去实例化,而是通过带参方法形式将UserDao传入过来,从而实现UserService对UserDao类的依赖
而实际创建对象的幕后对戏那个即是交给了外部来创建。
四个文件: UserDao.java, UserService.java, spring.xml, Start01.java
UserDao.java: Bean对象
UserService: Bean对象
spring.xml:配置文件
Start01.java: 测试文件
案例需求:UserService类中要使用UserDao类
// UserDao的Bean对象
package com.gtc.dao;
public class UserDao {
public void test(){
System.out.println("UserDao Test...");
}
}
package com.gtc.service;
import com.gtc.dao.UserDao;
import com.sun.deploy.panel.IProperty;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
// 常用对象String(日期类型)
private String host;
public void setHost(String host) {
this.host = host;
}
// 基本类型
private Integer port;
public void setPort(Integer port) {
this.port = port;
}
// List集合
private List list;
public void setList(List list) {
this.list = list;
}
// Set集合
private Set set;
public void setSet(Set set) {
this.set = set;
}
// Map对象
private Map map;
public void setMap(Map map) {
this.map = map;
}
// 属性Properties对象
private Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
}
public void test(){
System.out.println("UserService Test...");
userDao.test();
System.out.println(host);
System.out.println(port);
// 遍历List集合
for (String a : list){
System.out.println(a);
}
// 遍历Set集合
for (String a : set){
System.out.println(a);
}
// 遍历Map
for (Map.Entry entry : map.entrySet()){
System.out.println("MapKey = " + entry.getKey() + ", MapValue = " + entry.getValue());
}
// 遍历Properties
for (String key : properties.stringPropertyNames()){
System.out.println("ProKey = " + key + ", ProValue = " + properties.getProperty(key));
}
}
}
List上海
List杭州
List深圳
Set上海
Set杭州
Set深圳
properties北京
properties上海
properties杭州
// Start01.java测试文件
package com.gtc;
import com.gtc.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Start01 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
userService.test();
}
}
得到的输出:
UserService Test...
UserDao Test...
127.0.0.1
8080
List上海
List杭州
List深圳
Set上海
Set杭州
Set深圳
MapKey = 周杰伦, MapValue = 晴天
MapKey = 林俊杰, MapValue = 江南
MapKey = 陈奕迅, MapValue = 单车
ProKey = bj, ProValue = properties北京
ProKey = sh, ProValue = properties上海
ProKey = hz, ProValue = properties杭州
注:需提供带参构造器
package com.gtc.dao;
public class UserDao02 {
public void test(){
System.out.println("UserDao02 Test...");
}
}
package com.gtc.service;
import com.gtc.dao.UserDao02;
/**
* 构造器方法注入
* 需要提供带参构造
*/
public class UserService02 {
private UserDao02 userDao02;
/* 构造器注入 */
public UserService02(UserDao02 userDao02) {
this.userDao02 = userDao02;
}
public void test(){
System.out.println("UserService02 test...");
userDao02.test();
}
}
package com.gtc.test;
import com.gtc.service.UserService;
import com.gtc.service.UserService02;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Starter02 {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring02.xml");
UserService02 userService02 = (UserService02) beanFactory.getBean("userService02");
userService02.test();
}
}
将TypeDao类注入到TypeService类中,静态工厂的静态方法创建TypeDao,XML配置静态工厂。
package com.gtc.dao;
public class TypeDao {
public void test(){
System.out.println("TypeDao test...");
}
}
package com.gtc.service;
import com.gtc.dao.TypeDao;
public class TypeService {
private TypeDao typeDao;
public void setTypeDao(TypeDao typeDao) {
this.typeDao = typeDao;
}
public void test(){
System.out.println("TypeService test...");
typeDao.test();
}
}
package com.gtc.factory;
import com.gtc.dao.TypeDao;
/**
* 静态工厂注入
*/
public class StaticFactory {
public static TypeDao createTypeDao(){
return new TypeDao();
}
}
package com.gtc.test;
import com.gtc.service.TypeService;
import com.gtc.service.UserService;
import com.gtc.service.UserService02;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Starter02 {
public static void main(String[] args) {
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring02.xml");
TypeService typeService = (TypeService) beanFactory.getBean("typeService");
typeService.test();
}
}
略
注解方式注入Bean
对于bean的注入,除了使用xml配置以外,可以使用注解配置。注解的配置,可以简化配置文件,提高开发速度,使程序看上去更简洁。对于注解的解释,Spring对于注解有专门的解释器,对定义的注解进行解析,实现对应bean对象的注入,通过反射技术实现。
将UserDao注入到UserService中
1. 准备UserDao类
package com.gtc.dao;
public class UserDao {
public void test(){
System.out.println("UserDao test...");
}
}
2. 准备UserService类
package com.gtc.service;
import com.gtc.dao.UserDao;
import javax.annotation.Resource;
public class UserService {
// 注入JavaBean对象
@Resource
private UserDao userDao;
// set方法(也可以不要)
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void test(){
System.out.println("UserService test...");
userDao.test();
}
}
3. 修改spring.xml配置文件
4. 测试
package com.gtc.test;
import com.gtc.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App01 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
userService.test();
}
}
1. 注解默认通过属性字段名称查找对应的bean对象(属性字段名称与bean标签的id属性值一致)
2. 如果属性字段名称不一样,则会通过类型(Class)类型
3. 属性字段可以提供set方法,也可以不提供
4. 注解既可以声明在属性字段,也可以声明在set方法上
5. 可以设置注解的name属性,name属性值要与bean标签的id属性值一致
6. 当注入接口时,如果接口只有一个实现类,则正常实例化;如果接口有多个实现类,则需要使用name属性指定需要被实例化的bean对象
1. 注解默认使用Class类型去查找bean对象,与属性字段名称没有关系
2. 属性字段可以提供set方法,也可以不提供
3. 注解可以声明在属性级别,也可以声明在set方法级别
4. 如果想要通过指定名称查找bean对象,需要结合@Qualifier使用,通过value属性值查找bean对象(value属性值必须要设置,且值要与bean标签的id属性值对应)
实际的开发中,bean的数量非常多,采用手动配置bean的方式已无法满足生产需要,Spring这时候同样提供了扫描的方式,对扫描的bean对象统一进行管理,简化开发配置,提高开发效率。
Spring IOC 扫描器
作用:bean对象统一进行管理,简化开发配置,提高开发效率
1. 设置自动化扫描的范围:如果bean对象未在指定包范围,即时声明了注解,也无法实例化
2. 使用指定的注解(声明在类级别)bean对象的id属性默认是类的首字母小写
(1) 准备TypeDao类
package com.gtc.dao;
import org.springframework.stereotype.Repository;
@Repository
public class TypeDao {
public void test(){
System.out.println("TypeDao test...");
}
}
(2)配置IOC扫描器
(3) 测试
package com.gtc.test;
import com.gtc.dao.TypeDao;
import com.gtc.service.AccountService;
import com.gtc.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App01 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
TypeDao typeDao = (TypeDao) context.getBean("typeDao");
typeDao.test();
}
}
默认情况下,我们从Spring容器中拿到的对象均是单例的,对于bean的作用域类型如下:
注意:lazy-init是懒加载,如果等于true时作用是指Spring容器启动的时候不会去实例化这个bean,而是在程序调用才去实例化。默认是false即Spring容器启动时实例化。
默认情况下,被管理的bean只会IOC容器中存在一个实例,对于所有获取该Bean的操作Spring容器将只返回同一个Bean。
容器在启动的情况下 (即获取Spring上下文的情况下) 就实例化所有singleton的bean对象,并缓存于容器中。
Spring IOC容器在启动时,不会将bean对象实例化到容器中。