1.1简介
2002年,首次推出了spring框架的雏形,interface21框架
spring框架以interface21框架为基础经过重新设计,并不断丰富其内涵于于2004年3月24日发布了1.0正式版
Rod johnson 是spring Framework创始人,著名作者,他是悉尼大学博士,音乐专业,并非计算机。
spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架!
SSH:struct2+spring+Hibernate
SSM:springMVC+spring+Mybatis
官网:https://spring.io/projects/spring-framework#overview
官方下载地址: http://repo.spring.io/release/org/springframework/spring
GitHub:https://github.com/spring-projects/spring-framework
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version>
</dependency><!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.0.RELEASE</version>
</dependency>
优点
spring是一个开源免费的框架
spring是一个轻量级的,非入侵式的框架
控制反转(ioc),面向切面编程(aop)
支持事务的处理,对框架整合的支持
Spring就是一个轻量级的控制反转(IOC),和面向切面编程(AOP)的框架
组成
Spring AOP
Spring ORM
Spring Web
Spring WEB MVC
Spring DAO
Spring Context
Spring core
拓展
Spring Boot:一个快速开发的脚手架
基于SPringBoot可以快速的开发单个微服务
Spring Cloud
Spring Cloud 是基于SpringBoot实现的
以为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring及SPringMVC 承上启下的作用
Spring弊端:发展了太久,违背了原来的理念,配置十分繁琐.
IOC
之前开发步骤
1.UserDAO接口
2.UserDaompl实现类
3.UserService业务接口
4.UserServiceimpl业务实现类
之前的业务的客户需求可能会影响原来的代码,我们需要根据用户的需求修改源代码,如果程序代码量大,修改的成本会很大
使用set接口实现
private UserDao userdao
public void setuserDao(UserDao userDao){
this.userDao=uesrDao;
}
之前,程序主动创建对象,控制权在程序员手上
使用set注入,程序员不在具有主动性,而是成为了被动接收对象
这种思想,从本质上解决了问题,程序员不用再创建对象,系统的耦合性大大降低,可以更加专注业务的实现。这是IOC的原型。
IOC本质
控制反转IOC是一种设计思想,DI是实现ioc的一种方法,没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象转移给第三方
控制反转是一种通过描述(xml或注解)并通过第三方去生产或获取特定对象的方式,在spring中实现控制反转的是ioc容器,其实现的方法是依赖注入
Hello Spring
实体类
package com.yuan.pojo;
public class Hello {
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Hello{" +
"str='" + str + '\'' +
'}';
}
}
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">
<!--使用spring来创建对象,在spring中这些都称为bean
bean=对象,一个bean等于new了一个对象
id相当于 HELLO hello=new Hello
property相当给hello设定了一个值
-->
<!--ref spring容器创建的对象
value 具体的值,基本数据类型-->
<bean id="hello" class="com.yuan.pojo.Hello">
<property name="str" value="Spring"/>
</bean>
测试类
public class Mytest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello);
}
}
IOC创建对象的方式
使用无参构造创建对象
如果要使用有参构造,如下方式
<bean id="user" class="www.yuan.pojo.User">
第一种方法 <!--下标赋值法-->
<constructor-arg index="0" value="袁伟java"/>
</bean>
第二种方法<!--参数类型,不建议使用-->
<constructor-arg type="java.lang.String" value="袁伟"/>
</bean>
第三种方法<!--直接通过参数来设值-->
<constructor-arg name="name" value="袁伟"/>
</bean>
</beans>
在配置文件加载的时候,容器中管理的对象就已经被初始化了,实例化的对象就只有那一个,去多少次,始终是那一个!
Spring配置
1.别名
<bean id="user" class="www.yuan.pojo.User">
<constructor-arg name="name" value="袁伟"/>
</bean>
<alias name="user" alias="abc"/>
2.配置
<bean id="user" class="www.yuan.pojo.User">
id:bean的唯一标识符,也就是相当于我们学的对象名
class:bean对象所对应的权限定名:包名+类型
name:也是别名,可以去多个别名
3.import
import一般用于团队开发,可将多个配置文件,导入合并为一个
依赖注入
1.构造器注入
2.set方式注入
依赖:bean对象的创建依赖于容器
注入:bean对象中所有属性,由容器来注入
【环境搭建】
复杂类型
package com.yuan.pojo;
public class Address {
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
测试对象
package com.yuan.pojo;
import java.util.*;
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobby;
private Map<String,String> card;
private Set<String> games;
private Properties info;
private String wife;
beans
<bean id="student" class="com.yuan.pojo.Student">
<property name="name" value="袁伟"/>
</bean>
测试
public class Mytest {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) classPathXmlApplicationContext.getBean("student");
System.out.println(student.getName());
}
}
所有类型的注入方式
<bean id="address" class="com.yuan.pojo.Address"/>
<bean id="student" class="com.yuan.pojo.Student">
<!--普通注入-->
<property name="name" value="袁伟"/>
<!--bean注入,ref-->
<property name="address" ref="address"/>
<!--数组注入,ref-->
<property name="books">
<array>
<value>西游记</value>
<value>红楼梦</value>
<value>三国演义</value>
<value>水浒传</value>
</array>
</property>
<!--LIst集合-->
<property name="hobby">
<list>
<value>吉他</value>
<value>游泳</value>
<value>跑步</value>
</list>
</property>
<!--map集合-->
<property name="card">
<map>
<entry key="火" value="水"/>
</map>
</property>
<!--set-->
<property name="games">
<set>
<value>LOL</value>
<value>DNF</value>
</set>
</property>
<!--null-->
<property name="wife">
<null/>
</property>
<!--properties集合 值必须写在尖括号之间-->
<property name="info">
<props>
<prop key="姓名">袁伟</prop>
<prop key="城市">西安</prop>
</props>
</property>
</bean>
3.拓展方式注入
使用p命名和c命名注入
<!--p命名注入可以直接注入属性的值-->
<bean id="user" class="com.yuan.pojo.User" p:name="袁伟" p:age="24"/>
<!--c命名空间注入 可以通过构造器注入,construct-->
<bean id="user2" class="com.yuan.pojo.User" c:name="张峰" c:age="24"/>
</beans>
Bean的作用域
单例模式
<bean id="user2" class="com.yuan.pojo.User" c:name="张峰" c:age="24" scope="singleton"/>
原型模式:每次从容器中get的时候,都会产生一个新对象
<bean id="user2" class="com.yuan.pojo.User" c:name="张峰" c:age="24" scope="prototype"/>
其余的request,session,application这些只能在web开发应用
Bean的自动装配
自动装配是spring满足bean依赖一种方式
spring会在上下文自动寻找,并自动给bean装配属性
在spring中有三种装配方式
1.在xml中显示配置
2.在java中显示配置
3.隐式的自动配置bean
自动装配
方式一
<bean id="mao" class="com.yuan.pojo.cat"/>
<bean id="gou" class="com.yuan.pojo.dog"/>
<bean id="person" class="com.yuan.pojo.person" autowire="byName">
<!--byName会自动在容器上下文中查找。和自己对象set方法后面的值对应的beanid-->
<property name="name" value="袁伟"/>
方式二
<bean id="mao11" class="com.yuan.pojo.cat"/>
<bean id="gou11" class="com.yuan.pojo.dog"/>
<bean id="person" class="com.yuan.pojo.person" autowire="byType">
<!--byType会自动在容器上下文查找,和自己对象属性类型相同的对应的bean-->
<property name="name" value="袁伟"/>
byname,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性set方法的值一致
bytype,需要保证所有bean的class唯一,并且bean需要和自动注入的属性的类型一致
注解实现自动装配
jdk1.5支持的注解,spring2.5就支持注解
使用注解须知:
1.导入yueshu
2.配置注解的支持
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
@Autowire
beans.xml
<bean id="mao" class="com.yuan.pojo.cat"/>
<bean id="gou" class="com.yuan.pojo.dog"/>
<bean id="person" class="com.yuan.pojo.person">
实体类
public class person {
@Autowired
private dog gou;
@Autowired
private cat mao;
private String name;
//@Autowire 也可以放在set方法上,在属性上时,也可以不要set方法
如果@Autowire自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowire】完成的时候,我们可以使用@Qualifier(value=“xxx‘)去配置@AUtowire的使用,指定一个唯一的bean的注入
@Rescourse注解
public class people{
@Resource(name="cat")
private Cat cat;
@Rescource
private Dog dog;
}
//java注解
小结
都是用来自动装配,都可以放在字段上
@Autowire的默认方式是byType
@Rescource默认先通过byname,如果找不到名字,则通过bytype实现
使用注解开发
在spring4之后,要使用注解开发,必须保证aop的包导入了
使用注解需导入context约束,需要注解的支持
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
属性注入
//等价于<bean id="user" class="com.yuan.pojo.user"
@Component
public class User {
public String name;
public String getName() {
return name;
}
//相当于<property name="name" value="袁伟"
@Value("袁伟")
public void setName(String name) {
this.name = name;
}
}
衍生的注解
@component有几个衍生注解,在web开发中,会按照mvc三层架构分层
dao (@Repostory)
service(@service)
controller(@controller)
这几个衍生的注解功能都是一样的,都是代表将某个类注册到spring中,装配bean
使用java配置spring
//这个也会spring托管,注册到容器中,因为本来就是一个@component
//@Configuration 代表这是一个配置类,相当于之前的beans.xml
@Configuration
public class hello {
//注册一个bean,相当于之前的一个bean标签
//方法的名字相当于bean的id
//返回值,相当于class属性
@Bean
public User getUser(){
return new User();
}
}
public class User {
private String name;
public String getName() {
return name;
}
@Value("袁伟")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
public class Mytest {
public static void main(String[] args) {
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(hello.class);
User user = (User) annotationConfigApplicationContext.getBean("getUser");
System.out.println(user.getName());
}
}