1、Spring
interface 21 是前身
SSH :Struct2 + Spring + Hibernate(全自动的持久层框架)
SSM :SpringMVC + Spring + Mybatis(半自动持久层框架)
- Spring是一个开源的免费的框架(容器)
- Spring是一个轻量级的、非入侵(引入后不会改变原来代码的情况)的框架
- 控制反转(IOC)、面向切面编程(AOP)
- 支持(声明式)事务的处理,对(几乎所有)框架整合的支持
Spring就是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架
Spring是为了解决企业级应用开发的复杂性而创建的,简化开发
2、IOC本质
控制反转时一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的时IOC容器,其实现方法是依赖注入(Dependency Injection,DI)
3、HelloSpring
- 基于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">
<!--
使用spring来创建对象,在spring中这些称为bean
bean相当于new了对象
property相当于给对象中属性设置值
-->
<bean id="..." class="...">
<!--value:具体的值,ref:引用spring容器创建好的对象-->
<property name="" value=""/>
<property name="" ref=""/>
</bean>
</beans>
控制:传统应用程序的对象是由程序本身控制创建的,使用spring后,对象是由spring来创建的
反转:程序本身不创建对象,而变成被动的接收对象
依赖注入:利用set方式注入
- 实例化容器,加载配置元数据
//获取spring的上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext("xxx.xml");
context.getBean();
在getBean()的时候,实体类中的对象已经被创建
4、IOC创建对象方式
-
默认使用无参构造创建对象
-
若要使用有参构造创建对象,有三种方式:
- 通过下标赋值:
<bean id="user" class="com.xiong.pojo.User"> <constructor-arg index="0" value="xiong"/> </bean>
- 通过类型赋值
<!--不建议使用--> <bean id="user" class="com.xiong.pojo.User"> <constructor-arg type="java.lang.String" value="xiong1"/> </bean>
- 通过参数名:
<bean id="user" class="com.xiong.pojo.User"> <constructor-arg name="name" value="xiong2"/> </bean>
5、Spring配置
<!--
id:bean的唯一标识符
class:bean对象所对应的全限定名 包名+类名
name:别名,可以同时取多个,分隔符也可以不同
-->
<bean id="userT" class="com.xiong.pojo.UserT" name="t x,y" >
<property name="name" value="sunshine"/>
</bean>
alias别名,import导入多个配置文件
6、DI依赖注入
6.1、构造器注入
IOC有参创建对象的三种方式
6.2、set注入
依赖:bean对象的创建依赖于容器
注入:bean对象中的所有属性,有容器来注入
pojo实体类中属性:
private String name;
private Address address;
private String[] books;
private List<String> hobby;
private Map<String,String> card;
private Set<String> games;
private String wife;
private Properties info;
<?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 name="address" class="com.xiong.pojo.Address">
<property name="address" value="深圳"/>
</bean>
<bean name="student" class="com.xiong.pojo.Student">
<!--普通值注入-->
<property name="name" value="xiong"/>
<!--Bean注入-->
<property name="address" ref="address" />
<!--array-->
<property name="books">
<array>
<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="123546"/>
<entry key="银行卡" value="12365164546"/>
</map>
</property>
<!--set-->
<property name="games">
<set>
<value>LOL</value>
<value>cs</value>
<value>cf</value>
</set>
</property>
<!--null-->
<property name="wife">
<null/>
</property>
<!--properties key-value-->
<property name="info">
<props>
<prop key="学号">2013041111</prop>
<prop key="性别">男</prop>
<prop key="username">sunshine</prop>
<prop key="password">123</prop>
</props>
</property>
</bean>
</beans>
6.3、p,c命名空间
导入p,c命名的约束
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
p命名空间注入:
<!--p命名空间注入(set注入 property)-->
<bean name="user" class="com.xiong.pojo.User" p:name="sunshine" p:age="18"/>
c命名空间注入:
<!--c命名空间注入(构造器注入 constructor-arg)-->
<bean name="userc" class="com.xiong.pojo.User" c:name="sunshine" c:age="16"/>
7、bean的作用域
Scope:
- Singleton 单例 全局唯一 spring的默认机制
- prototype 原型 每次从容器中get时,都会产生一个新的对象
- request web开发中使用
- session web开发中使用
- application web开发中使用
- websocket
8、bean的自动装配
- 自动装配(Autowired):
- spring会在上下文中自动寻找,并自动给bean装配属性
三种装配方式:
- 在xml中显示的配置
- 在Java中显示配置
- 隐式的自动装配
People类中的属性:
private Cat cat;
private Dog dog;
private String name;
8.1、byName自动装配
<bean id="dog" class="com.xiong.pojo.Dog"/>
<bean id="cat" class="com.xiong.pojo.Cat"/>
<!--
byName:会自动在容器上下文中查找和自己对象 set方法后面的值 对应的 bean的id
-->
<bean id="people" class="com.xiong.pojo.People" autowire="byName">
<property name="name" value="sunshine"/>
</bean>
8.2、byType自动装配
<bean id="dog" class="com.xiong.pojo.Dog"/>
<bean id="cat" class="com.xiong.pojo.Cat"/>
<!--
byType:会自动在容器上下文中查找和自己对象 属性类型相同的 对应的 bean的id (弊端:类型得全局唯一)
-->
<bean id="people" class="com.xiong.pojo.People" autowire="byType">
<property name="name" value="sunshine"/>
</bean>
- byName时候需要保证bean的id唯一
- byType的时候需要保证bean的class唯一
8.3、注解实现自动装配
- 导入注解约束 context
- 配置注解支持
<context:annotation-config/>
<?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/>
<bean id="dog" class="com.xiong.pojo.Dog"/>
<bean id="cat" class="com.xiong.pojo.Cat"/>
<bean id="people" class="com.xiong.pojo.People" />
</beans>
@Autowired
直接在属性上使用,也可以在set方法上使用
若环境复杂,可以配合使用@Qualifier(value = “[bean的id]”)指定装配的bean
@Autowired
@Qualifier(value = "cat")
private Cat cat;
@Autowired
private Dog dog;
private String name;
若某个字段标注了@Nullable说明该字段可以为空
若显示的定义了@Autowired(request = false) 说明这个对象可以为null,否则不允许
@Resource
@Resource(name = "cat")
private Cat cat;
@Resource
private Dog dog;
private String name;
@Resource和@Autowired的区别:
- 都用来自动装配,
- @Autowired 通过byType方式实现 [常用]
- @Resource先通过byName的方式,后通过byType的方式
9、注解说明
9.1、bean,属性注入
- @Component:放在类上,用来注册bean
- @Value(“”):给对应的属性注入值
9.2、衍生的注解
- @Component的衍射注解(按照MVC三层架构分层):
- dao [@Repository]
- service [@Service]
- controller [@Controller]
注解功能相同,将类注册到Spring中,装配bean
9.3、自动装配
-
@Autowired:通过类型自动装配
- 如果@Autowired不能自动装配,需要通过@Qualifier(value=“对应bean的id”)
-
@Nullable:标记字段,该字段可以为null
-
@Resource:通过名字,类型自动装配
9.4、作用域
- @Scope(“singleton”):单例模式
- @Scope(“prototype”):原型模式
10、Spring配置(JAVA)
不适用spring的xml配置,交给java来做
JavaConfig是Spring的一个子项目,在Spring4之后成为了一个核心功能
//@Component说明这个类被Spring接管了,注册到了容器中
@Component
public class Student {
private String name;
public String getName() {
return name;
}
@Value("sunshine")
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
//@Configuration代表这是一个配置类
@Configuration
@ComponentScan("com.xiong.pojo")
public class MyConfig {
//注册一个bean,相当于bean标签
//方法名字,相当于bean标签中的id属性
//返回值,相当于bean标签中的class属性
@Bean
public Student getStudent(){
return new Student();
}
}
使用JAVA配置,只能通过AnnotationConfig上下文来获取容器,通过配置类的class对象加载
public class MyTest {
@Test
public void TestConfig(){
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
Student getStudent = context.getBean("getStudent", Student.class);
System.out.println(getStudent.getName());
}
}
11、Aop在Spring中的作用
提供声明式事务:允许用户自定义切面
- 横切关注点:与我们业务逻辑无关,但是我们需要关注的部分。如日志,安全,缓存,事务
- 切面(ASPECT):横切关注点 被模块化 的特殊对象。为一个类
- 通知(Advice):切面必须完成的工作。为类中的一个方法
- 目标(Target):被通知对象。InvocationHandler
- 代理(Proxy):向目标对象应用通知之后创建的对象。InvocationHandler
- 切入点(PointCut):切面通知 执行的"地点"的定义
- 连接点(JoinPoint):与切入点匹配的执行点
12、事务管理
事务的ACID原则:原子性,一致性,隔离性,持久性
11.1、spring中事务管理
- 声明式事务:AOP
- 编程式事务:需要在代码中进行事务的管理