spring:译为春天-----给软件行业带来了春天
2202,首次推出了spring框架的雏形,interface21框架!
spring框架即以interface21框架为基础,经过重新设计,并不断丰富其内涵,于2003年3月24日发布了1.0正式版。
Rod Johnson,spring framework创始人,著名作者。很难想象Rod Johnson的学历,真的让好多人大吃一惊,他是悉尼大学的博士,然而他的专业是音乐
使现有的技术更加容易使用,是个大杂烩
SSH: Struct2 + Spring + Hibernate
SSM:SpringMVC + Springl + Mybatis
需要导入的依赖
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.2.6.RELEASEversion>
dependency>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ioET5T6Q-1592046354066)(C:\Users\d1320\Desktop\1219227-20170930225010356-45057485.gif)]
因为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring及SpringMVC!承上启下的作用
弊端:Spring发展了太久之后,违背了原来的理念!配置十分繁琐,被称为“配置地狱”
1 . UserDao 接口
public interface UserDao {
void getUser();
}
2.UserDaoImpl实现类
public void getUser(){
System.out.println("默认获取用户的数据");
}
3.UserService业务接口
public interface UserService {
void getUser();
void setUserDao(UserDao userDao);
}
4.UserServiceImlp业务实现类
private UserDao userDao;
//利用set进行动态实现值的注入
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void getUser() {
userDao.getUser();
}
在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求取修改源代码。如果代码量非常大,修改一次的成本价十分昂贵。
我们使用一个Set接口实现
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
IOC本质
控制反转IOC是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法,没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了
采用XML方式配置Bean的时候,Bean的定义信息和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的星是定义在实现类中,从而达到类零配置的目的。
控制反转时一种通过描述(XML或注解)并通过第三方取生产或获取特定的对象的方式,在spring中实现控制反转的是IOC容器,其实现方法是依赖注入
这个过程就叫控制反转:
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用spring后,对象是由spring来创建的
反转:程序本身不创建对象,而变成被动的接受对象
依赖注入:就是利用set方法来进行注入的
ioc是一种编程思想,由主动的编程变成被动的接受
可以通过newClassPathXmlApplicationContext去浏览以下底层源码
ok,到了现在,我们彻底不用再程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的ioc就是:对象由spring创建,管理,装配
1、使用无参构造创建对象,默认!
2、假设我们要使用有参构造创建对象。
1、下标赋值
<bean id="user" class="host.qianlong.pojo.User">
<constructor-arg index="0" value="breaking">constructor-arg>
bean>
2、类型
<bean id="user" class="host.qianlong.pojo.User">
<constructor-arg type="java.lang.String" value="qianloing"/>
bean>
3.通过参数名来设置
<bean id="user" class="host.qianlong.pojo.User">
<constructor-arg name="name" value="qianlong"/>
bean>
总结:在配置文件加载的时候,容器中管理的对象已经初始化了!
<alias name="user" alias-"userNew">alias>
这个import,一般用于团队开发使用,它可以将多个配置文件,导入合并为一个
假设,现在项目有多个人开发,这三个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的!
<bean id="address" class="host.qianlong.pojo.Address" >
<property name="address" value="xian"/>
bean>
<bean id="student" class="host.qianlong.pojo.Student">
<property name="name" value="qianlong"/>
<property name="address" ref="address"/>
<property name="books">
<array>
<value>三国演义value>
<value>水浒传value>
<value>西游记value>
<value>红楼梦value>
array>
property>
<property name="hobbies">
<list>
<value>唱歌value>
<value>跳舞value>
<value>写代码value>
list>
property>
<property name="games">
<set>
<value>NBAvalue>
<value>CFvalue>
<value>LOLvalue>
set>
property>
<property name="card">
<map>
<entry key="1" value="qianlong">entry>
<entry key="2" value="zhangna">entry>
map>
property>
<property name="wife">
<null/>
property>
<property name="info">
<props>
<prop key="username">123prop>
<prop key="password">456prop>
props>
property>
bean>
1.单例模式
<bean id="user" class="host.qianlong.pojo.User" scope="singleton"/>
2.原型模式:每次从容器中get的时候,都会产生一个新对象
<bean id="accountService" class="com.someting.DefaultAccountService"/>
3.其余的request,session,application、这些只能再web开发中使用到
在spring中有三种装配的方式
1.在xml中显示的配置
2.在java中显示配置
3.隐式的自动装配bean
<bean id="person" class="host.qianlong.pojo.Person" autowire="byName">
<property name="name" value="qianlong"/>
<property name="dog" ref="dog"/>
<property name="cat" ref="cat"/>
bean>
<bean id="person" class="host.qianlong.pojo.Person" autowire="byType">
<property name="name" value="qianlong"/>
<property name="dog" ref="dog"/>
<property name="cat" ref="cat"/>
bean>
小结:
byName:需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致 byType:需要保证所有的bean的class唯一,并且这个bean需要和自动注入的属性的类型一致
jdk1.5支持的注解,spring2.5就支持注解了
要使用注解须知:
1.导入约束:context约束
2.配置注解的支持:context:annotation-config/
<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>
@Autowired
直接在属性上使用即可!也可以在set方式上使用
使用Autowired我们可以不用编写Set方法了,前提式你这个自动装配的属性在IOC(Spring)容器中存在,且符合全名字ByName
科普
@Nullable 字段标记了这个注解 说明这个字段可以为null
public @interface Autowired{
boolean required() default true;
}
测试代码
//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
private String name;
@Autowired(required = false)
private Cat cat;
@Autowired
private Dog dog;
如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以使用@Qualifier(value=‘xxx’)去设置@Autowired的使用,指定一个唯一的bean对象注入!
// @Qualifier(value = "cat2")
private Cat cat;
小结:
@Resource和@Autowired的区别:
都是用来自动装配的,都是可以放在属性字段上
@Autowired通过ByType的方式实现,而且必须要求这个对象存在
@Resource默认通过Byname的方式实现那,如果找不到名字,则通过哟ByType实现,如果连个都找不到的情况下,就会报错!
执行顺序不同:@Autowired通过ByType的方式实现!
1.bean
2.属性如何注入
@Value("tongmeng")
//相当于
public String name = "qianlong";
3.衍生的注解
@Componer有几个衍生注解,在我们web开发中,会按照mvc三层架构分层!
这四个注解功能都是一样的,都是代表某个类注册到spring中,装配bean
4.自动装配置
## 注解说明 - @Autowired:自动装配通过类型,名字 如果@Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value='xxx') - @Nullable:字段标记了这个注解,说明这个字段可以为null - @Resource:自动装配,通过名字,类型
5.作用域
@Component
@Scope("property")
public class User {
@Value("tongmeng")
//相当于
public String name = "qianlong";
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
6.小结
xml与注解:
* xml更加万能,适用于任何场合,维护简单方便
* 注解 不是自己类使用不了,维护相对复杂
xml与注解最佳时间:
xml用来管理bean;
注解只负责完成属性的注入:
我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持
<context:component-scan basepackage="host.qianlong.pojo"/>
角色分析:
代码步骤:
1.接口
public interface Rent{
void rent();
}
2.真实角色
public class Host implements Rent{
public void rent(){
System.out.println("房东要出租房子")
}
}
3.代理角色
public class Proxy implements Rent{
private Host host;
public Proxy() {
}
public Proxy(Host host) {
this.host = host;
}
public void aa() {
seeHouse();
host.aa();
pact();
fare();
}
//看房
public void seeHouse(){
System.out.println("中介带你看房子");
}
//签合同
public void pact(){
System.out.println("签租赁合同");
}
//收中介费
public void fare(){
System.out.println("收取服务费");
}
}
4.客户端访问代理角色
public class Client {
public static void main(String[] args) {
//房东需要租房子
Host host = new Host();
//代理,中介帮房东租房子,但实际呢?代理一般慧有一些负数操作
Proxy proxy = new Proxy(host);
//你不用找房东,直接找中介租房即可
proxy.aa();
}
}
优点:
缺点:
需要了解两个类:Proxy:代理,InvocationHandler:调用处理程序
动态代理的好处:
事务ACID原则:
为什么需要事务?