spring5 IOC学习
1.spring简介
spring理念:说现在技术更加容易,本身说一个大杂烩,为企业应用开发提供方便。
- SSM: SpringMVC + Spring + Mybatis
- SSH: Struct2 + Spring + Hibernate
官网: https://spring.io/projects/spring-framework#overview
官方下载: https://repo.spring.io/release/org/springframework/spring/
GitHub: https://github.com/spring-projects/spring-framework
Spring Web MVC » 5.2.5.RELEASE
<!--导入的依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!--整合mybatis-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
优点:
1. spring是开源的免费的容器。
2. spring是一个轻量级的,非入侵式的。
控制反转(IOC),面向切面编程 (AOP)。
3. 支持事务处理,对框架整合的支持。
总结:spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架。
IOC理论
- UserDao
- UserDaoImpl
- UserService
- UserServiceImpl
传统的创建对象通过直接new 创建,自己的理解(例如如果用户需求改变,需要通过service的实现方法改变,新建一个实现类重新在方法中new 太过繁琐,若我们不通过new 创建 而是将创建对象 交给其他,我们只需要的需求导入(XML方式修改),这样就避免了麻烦)
狂神:
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
之前是主动创建对象,控制权在程序员手上。
使用set之后,是被动接受对象。
Hello Spring
pojo
package com.hou.pojo;
public class Hello {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Hello{" +
"name='" + name + '\'' +
'}';
}
}
spring的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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--bean = 对象-->
<!--id = 变量名-->
<!--class = new的对象-->
<!--property 相当于给对象中的属性设值-->
<bean id="hello" class="com.hou.pojo.Hello">
<property name="name" value="Spring"/>
</bean>
</beans>
test中
import com.hou.pojo.Hello;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Mytest {
public static void main(String[] args) {
//获取spring上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//我们的对象下能在都在spring·中管理了,我们要使用,直接取出来就可以了
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello.toString());
}
}
IOC创建对象的方式
- 使用无参构造对象,默认
- 使用有参构造
下标赋值
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.hou.pojo.User">
<constructor-arg index="0" value="hou"/>
</bean>
</beans>
类型赋值(不建议使用)
<bean id="user" class="com.hou.pojo.User">
<constructor-arg type="java.lang.String" value="dong"/>
</bean>
直接通过类名
<bean id="user" class="com.hou.pojo.User">
<constructor-arg name="name" value="hou"></constructor-arg>
</bean>
Spring类似与中介
Spring配置
别名
<bean id="user" class="com.hou.pojo.User">
<constructor-arg name="name" value="hou"></constructor-arg>
</bean>
<alias name="user" alias="user2aaa"/>
Bean的配置
- id:bean的id标识符
- class:bean对象所对应的类型
- name:别名,更高级,可以同时取多个别名。
import
一般用于团队开发,它可以将多个配置文件,导入合并为一个
<import resource="beans.xml"/>
6.依赖注入
-
构造器注入
-
set方式注入(重点)
依赖:bean对象的创建依赖于容器
注入:bean对象中的所有属性,由容器来注入
【环境搭建】
复杂类型
真实测试对象
package com.pojo;
import java.util.*;
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbies;
private Map<String, String> card;
private Set<String> game;
private Properties infor;
private String wife;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", address=" + address +
", books=" + Arrays.toString(books) +
", hobbies=" + hobbies +
", card=" + card +
", game=" + game +
", infor=" + infor +
", wife='" + wife + '\'' +
'}';
}
}
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Address{" +
"address='" + address + '\'' +
'}';
}
}
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="address" class="com.pojo.Address">
<property name="address" value="xian"></property>
</bean>
<bean id="student" class="com.pojo.Student">
<property name="name" value="hou"/>
<property name="address" ref="address"/>
<!--数组注入-->
<property name="books">
<array>
<value>三国</value>
<value>西游</value>
<value>水浒</value>
</array>
</property>
<!--list-->
<property name="hobbies">
<list>
<value>eat</value>
<value>drink</value>
<value>play</value>
</list>
</property>
<property name="card">
<map>
<entry key="1" value="12"/>
<entry key="2" value="23"/>
</map>
</property>
<property name="game">
<set>
<value>wangzhe</value>
<value>daota</value>
<value>lol</value>
</set>
</property>
<property name="wife">
<null></null>
</property>
<!--properties-->
<property name="infor">
<props>
<prop key="id">20200405</prop>
<prop key="name">hdk</prop>
</props>
</property>
</bean>
</beans>
第三方
p标签和c标签
<?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--p命名空间注入/set注入-->
<bean id="use" class="com.pojo.User" p:name="dong" p:age="10">
</bean>
<!--c命名空间/构造器-->
<bean id="use2" class="com.pojo.User" c:name="kun" c:age="19"></bean>
</beans>
bean的作用域
1.单例模式
<bean id="use2" class="com.pojo.User" c:name="kun" c:age="19" scope="singleton"></bean>
2.原型模式
<bean id="use2" class="com.pojo.User" c:name="kun" c:age="19" scope="prototype"></bean>
3.其余的request、session、application这些只能在web开放中使用!
7.Bean的自动装配
自动装配是Spring是满足bean依赖的一种方式
Spring会在上下文自动寻找,并自动给bean装配属性
在Spring中有三种装配的方式:
- 在xml中显示配置
- 在java中显示配置
- 隐式的自动装配bean 【重要】
环境搭建:一个人有两个宠物
- Byname自动装配:byname会自动查找,和自己对象set对应的值对应的id
保证所有id唯一,并且和set注入的值一致
- Bytype自动装配:byType会自动查找,和自己对象属性相同的bean
保证所有的class唯一
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="cat11" class="com.pojo.Cat"/>
<bean id="dog" class="com.pojo.Dog"/>
<!--byname会自动查找,和自己对象set对应的值对应的id-->
<!--<bean id="people" class="com.pojo.People" autowire="byName">-->
<!--<property name="name" value="hou"></property>-->
<!--</bean>-->
<!--byType会自动查找,和自己对象属性相同的bean-->
<bean id="people" class="com.pojo.People" autowire="byType">
<property name="name" value="hou"></property>
</bean>
</beans>
package com.pojo;
public class People {
private Cat cat;
private Dog dog;
private String name;
@Override
public String toString() {
return "People{" +
"cat=" + cat +
", dog=" + dog +
", name='" + name + '\'' +
'}';
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
使用注解自动准装配
jdk1.5支持的注解,spring2.5支持的注解
The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML.
导入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>
@Autowire
在属性上个使用,也可以在set上使用
我们可以不用编写set方法了
public class People {
@Autowired
private Cat cat;
@Autowired
private Dog dog;
private String name;
}`
如果@Autowired自动装配环境比较复杂。自动装配无法通过一个注解完成的时候
我们可以使用@Qualifier(value = “dog”)去配合使用,指定一个唯一的id对象
public class People {
@Autowired
private Cat cat;
@Autowired
@Qualifier(value = "dog")
private Dog dog;
private String name;
}
@Resource(name=“dog”)也可以
区别:
@autowire通过byType实现,而且必须要求这个对象存在
@resource默认通过byName实现,如果找不到,通过byType实现
8.使用注解开发
<?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/>
<!--指定要扫描的包-->
<context:component-scan base-package="com.pojo"/>
</beans>
- 属性注入
@Component
public class User {
@Value("dong")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
- 衍生的注解
@Component有几个衍生注解,会按照web开发中,mvc架构中分层。
dao (@Repository)
service(@Service)
controller(@Controller)
这四个注解功能一样的,都是代表将某个类注册到容器中
使用java方式配置注解(纯注解)
@Configuration //这个也会被spring容器托管,注册到容器中,因为他本来就是一个@Component
//相当于beans.xml文件
@ComponentScan("com.pojo")
@Import(Config2.class)
public class MyConfig {
@Bean
public User getUser(){
return new User();
}
}