Spring就像是整个项目中装配bean(对象)的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。也可以称之为项目中的粘合剂。Spring的核心思想是IoC(控制反转),即不再需要程序员去显式地new一个对象,而是让Spring框架帮你来完成这一切。(包括:对象的创建、对象之间的关系)
- 轻量:Spring 框架运行占用的资源少,运行效率高。不依赖其他 jar
- 针对接口编程,解耦合:Spring 提供了 Ioc 控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的对象创建方式,现在由容器完成。对象之间的依赖解耦合。
- AOP 编程的支持:通过 Spring 提供的 AOP 功能,方便进行面向切面的编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松应付。
- 方便集成各种优秀框架:Spring提供了对各种优秀框架(如 Struts,Hibernate、MyBatis)等的直接支持。简化框架的使用。Spring 像插线板一样,其他框架是插头,可以容易的组合到一起。
- 最大的缺点就是:配置繁琐,启动慢
- 经常要考虑第三方工具的兼容性
- 项目的依赖管理耗时耗力
Spring最主要的学习内容:两个核心 :Ioc+Aop
Spring框架是一个软件,其它人写好的软件,所以我们要掌握的就是:
目的:管理对象
Spring的核心思想是IOC(控制反转),把对象的控制权给了Spring,(底层是通过反射)即:不再需要程序员去显式地new一个对象,而是让Spring框架帮你来完成这一切。
IOC控制反转:(Inversion Of Control),即就是:将对象的控制权从自己new改为跟Spring要;
DI 是ioc的技术实现
- 添加依赖。
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.2.5.RELEASEversion>
dependency>
2.创建类、接口、实现类。Spring在MVC三层架构中是针对service层的框架。
3.Spring配置文件。通常命名为:applicationContext.xml。该文件类似Servlet的web.xml,在配置文件中注册类,这样Spring才能完成IOC
<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="someService" class="com.xd.service.impl.SomeServiceImpl">bean>
<bean id="someService1" class="com.xd.service.impl.SomeServiceImpl" scope="prototype">bean>
<bean id="myDate" class="java.util.Date">bean>
beans>
4. 测试类中创建Spring容器,调用Spring容器中的方法可以创建对象、获取对象的信息。
@Test
public void test02(){
//使用spring容器创建的对象
//1.指定spring配置文件的名称
String config="applicationContext.xml";
//2.创建表示spring容器的对象, ApplicationContext
// ApplicationContext就是表示Spring容器,通过容器获取对象了
// ClassPathXmlApplicationContext:表示从类路径中加载spring的配置文件
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//从容器中获取某个对象, 你要调用对象的方法
//getBean("配置文件中的bean的id值")
SomeService service = (SomeService) ac.getBean("someService");
//使用spring创建好的对象
service.doSome();
}
/*
以下代码的执行原理:通过ClassPathXmlApplicationContext创建容器对象,创建容器对象的同时,ClassPathXmlApplicationContext会根据配置文件的路径去解析配置文件,解析的过程会将配置文件中所有标签中的类创建对象,默认调用无参构造方法,之后将创建好的对象以及bean标签的id保存在map中,其中id为key。在测试文件中可以调用容器对象ac的getBean方法通过id获取创建好的对象,要强转,然后调用对应方法。
*/
public void test06(){
String path = "applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(path);
Date nowTime = (Date)ac.getBean("myDate");
System.out.println(nowTime);
}
注意:
//创建容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//根据bean标签的id获取创建好的对象,getBean返回Object类型,要强转。通过service调用该类的方法
SomeService service = (SomeService) ac.getBean("someService");
//获取容器中定义的对象的数量
int nums = ac.getBeanDefinitionCount();
//容器中每个定义的对象的名称,知道了对象的名称,就可以通过getBean获取创建好的对象。
String[] names = ac.getBeanDefinitionNames();
具体实现:
<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="myStudent" class="com.xd.ba02.Student">
<property name="name" value="张三"/>
<property name="age" value="20"/>
<property name="email" value="[email protected]"/>
<property name="school" ref="mySchool"/>
bean>
<bean id="mySchool" class="com.xd.ba02.School">
<property name="name" value="西安电子科技大学"/>
<property name="address" value="西安市雁塔区"/>
bean>
<bean id="myStudent" class="com.xd.ba03.Student">
<constructor-arg name="name" value="张三"/>
<constructor-arg name="age" value="20"/>
<constructor-arg name="school" ref="mySchool"/>
bean>
<bean id="myStudent1" class="com.xd.ba03.Student">
<constructor-arg index="0" value="李四"/>
<constructor-arg index="1" value="22"/>
<constructor-arg index="2" ref="mySchool"/>
bean>
<bean id="myStudent2" class="com.xd.ba03.Student">
<constructor-arg value="李四"/>
<constructor-arg value="22"/>
<constructor-arg ref="mySchool"/>
bean>
<bean id="mySchool" class="com.xd.ba03.School">
<property name="name" value="西安xxx大学"/>
<property name="address" value="西安市雁塔区"/>
bean>
<bean id="myFile" class="java.io.File">
<constructor-arg name="parent" value="F:\计算机\Java学习\SSM\04-Spring\源码\ch02-di-xml"/>
<constructor-arg name="child" value="readme.txt"/>
bean>
<context:component-scan base-package="com.xd.ba01"/>
@Component: 创建对象的, 等同于的功能。
//使用value属性,指定对象名称
//@Component(value = "myStudent")
//不指定对象名称,由spring提供默认名称: 类名的首字母小写
//@Component
@Component("myStudent") //常用
public class Student {
private String name;
private int age;
public Student() {
System.out.println("student无参构造方法执行");
}
setter
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
- @Respotory、@Service、@Controller这三个注解与Component功能类似,都是创建对象。但是又有其特殊的用途,是给项目的对象分层的。
- @Repository(用在持久层类的上面) : 放在dao的实现类上面,表示创建dao对象,dao对象是能访问数据库的。
- @Service(用在业务层类的上面):放在service的实现类上面,创建service对象,service对象是做业务处理,可以有事务等功能的。
- @Controller(用在控制器的上面):放在控制器(处理器)类的上面,创建控制器对象的,控制器对象,能够接受用户提交的参数,显示请求的处理结果。
- 对于@Component、@Respotory、@Service、@Controller。毋庸置疑的是,持久层dao用@Respotory、业务层用@Service、页面层用@Controller。对于其它不在这三层的类,但是又想创建对象,就用@Component注解。
- @Value注解的作用是给对象简单类型属性赋值。
- 属性:@Value注解里的值必须是String类型,赋的值要用双引号括起来
- 位置:
1. 在属性定义的上面,无需set方法,推荐使用。底层用反射快。
2. 在set方法的上面使用,调set方法。
@Component("myStudent")
public class Student {
@Value("张三")
private String name;
@Value("20")
private int age;
//@Value("20") 调set方法
public void setAge(int age) {
System.out.println("student的set方法执行了");
this.age = age;
}
}
@Autowired注解的作用是给对象引用类型属性赋值。使用的是自动注入原理 ,支持byName, byType。默认byType。
位置:
@Autowired //按byType注入
private School school;
如果要使用byName方式,需要做的是:
@Component("mySchool")
public class School {
}
@Autowired
@Qualifier(value = "mySchool") //mySchool为id
private School school;
@Autowired注解的request属性,是一个boolean类型的,默认true。一般使用true,方便排错。
//@Autowired(required = true) 默认
//@Autowired(required = false)不报错,不建议用
@Autowired
@Qualifier(value = "mySchool")
private School school;
@Resource: 来自jdk中的注解,spring框架提供了对这个注解的功能支持,完成引用类型的自动注入,支持byName,byType。默认byName
位置:
@Component("school")
public class School {
}
@Resource //默认是byName: 先使用byName自动注入,如果byName赋值失败,再使用byType
private School school;
@Resource只使用byName方式,需要增加一个属性 name,name的值是bean的id(名称)
@Resource(name = "mySchool")
private School school;