狂神Spring笔记

Spring入门学习

一、Spring

1.1、简介

  • Spring:春天------>给软件行业带来了春天!

  • 2002,首次推出了Spring框架的雏形: interface21框架!

  • Spring框架即以interface21框架为基础,经过重新设计;并不断丰富其内涵,于2004年3月24日,发布了1.0正式版。

  • Rod Johnson ,Spring Framework创始人,著名作者。

  • spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架!

    SSH : Struct2 + Spring +Hibernate!
    SSM : SpringMvc + Spring + Mybatis!

  • 官网:https://lspring.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.10.RELEASE</version>
</dependency>

1.2、优点

  • Spring是一个开源的免费的框架(容器)!
  • Spring是一个轻量级的、非入侵式的框架!
  • 控制翻转(IOC),面向切面编程(AOP)
  • 支持事务的处理,对框架整合的支持!

总结一句话: Spring就是一个轻量级的控制反转(IOC)和面向切面(AOP)编程的框架!

1.3、组成

20171127110222693.jpg

1.4、拓展

在spring的官网有这个介绍,现代化的java开发!说白就是基于spring的开发

在这里插入图片描述

  • springBoot
    • 一个快速开发的脚手架
    • 基于SpringBoot可以快速的开发单个微服务
    • 约定大于配置
  • SpringCloud
    • SpringCloud是基本SpringBoot

因为现在大多数公司都在使用SpringBoot进行快速开发,学习SpringBoot的前提,需要完全掌握Spring及SpringMVC!承上启下的作用!

弊端:发展了太久之后,违背原来的理念!配置十分繁琐,人称:”配置地狱!“

二、IOC理论推导

2.1、环境搭建及简单实现

1.UserDao接口

2.UserDaolmpl实现类

3.UserService 业务接口

4.UserServicelmpl 业务实现类

2.2、实现一个IOC

在我们之前的业务中,用户的需求可能会影响我们原来的代码,我们需要根据用户的需求去修改原代码!如果程序代码量十分大,修改一次的成本代价十分昂贵!

我们使用一个Set接口实现.

public void setUserDao(UserDao userDao) {
    this.userDao = userDao;
}
  • 之前都是程序主动创建对象,控制权在程序员手里
  • 使用set注入之后,程序不再具有主动性 ,而变成了被动的接受对象!

这种思想,从本质上解决了问题,我们程序猿不用再去管理对象的创建了。系统的耦合性大大降低~,可以更加专注的在业务的实现上!

基础实现:

//用户实际调的是业务层,Dao层他们不需要接触
UserService userService =new UserServiceImpl();

userService.setUserDao(new UserDaoMysqImpl());
userService.getUser();

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,
Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
**控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是loC容器,其实现方法是依赖注入(Dependency Injection,Dl) 。**I

<! --使用Spring米创建对象,在Spring这些都称为Bean
类型 变量名 = new类型();
Hello hello = new HelLo( );
id =变量名
class = new的对象;
property相当于给对象中的属性设置一个值!-->

2.3、思考问题?

  • Hello对象是谁创建的?
    hello 对象是由Spring创建的

  • Hello对象的属性是怎么设置的?
    hello 对象的属性是由Spring容器设置的,

    这个过程就叫控制反转:
    控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后,对象是由Spring来创建的.
    反转∶程序本身不创建对象,而变成被动的接收对象

依赖注入:就是利用set方法来进行注入的
IOC是一种编程思想,由主动的编程变成被动的接收
可以通过newClassPathXmlApplicationContext去浏览一下底层源码
OK,到了现在,我们彻底不用再程序中去改动了,要实现不同的操作,只需要在xml配置文件中进行修改,所谓的loc,一句话搞定:对象由Spring 来创建,管理,装配!

2.4、控制翻转IOC简单实例:

<bean id="UserDaoImpl" class="com.LH.Dao.UserDaoImpl"/>
<bean id="UserDaoMysqImpl" class="com.LH.Dao.UserDaoMysqImpl"/>

<bean id="UserServiceImpl" class="com.LH.service.UserServiceImpl">
    <property name="userDao"  ref="UserDaoMysqImpl"/>
</bean>
//获取ApplicationContext,拿到Spring容器
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//容器在手,天下我有,用什么都用get取就完事
UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("UserServiceImpl");

userServiceImpl.getUser();
System.out.println(userServiceImpl);

三、IOC创建对象的方式

3.1、使用无参构造创建对象,默认

<bean id="user" class="com.LH.pojo.User">
    <property name="name" value="文静"/>
</bean>
public User() {
    System.out.println("使用无参构造方法");
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public  void show(){
    System.out.println("name"+name);
}
public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

    User user = (User) context.getBean("user");
    user.show();
}

结果:

使用无参构造方法
name文静

3.2、使用有参构造构造对象

1.下标赋值

<bean id="user" class="com.LH.pojo.User">
        <!-- 下标赋值-->
        <constructor-arg index="0" value="文静"/>
    </bean>

2.类型

<!--类型赋值 不建议使用-->
<constructor-arg type="java.lang.String" value="文静"/>

3.参数名(掌握)

<!--直接通过参数名-->
<constructor-arg name="name" value="文静"/>

注意:在配置文件加载的时后,spring容器中的对象就已经被初始化了

四、spring配置

4.14、别名 alias

<!--别名,添加了别名,也可以使用别名获取对象-->
    <alias name="user" alias="userNew"/>

4.2、bean

<!--
id : bean 的唯一标识符,也就是相当于我们学的对象名
cLass : bean对象所对应的全限定名:包名+类型
name :也是别名,而且iname 可以同时取多个别名
-->
<bean id="userT" class="com.kuang.pojo.UserT" name="user2 u2,u3;u4">
<property name="name" value="西部开源"/>
</bean>

4.3、import

多用于团队开发使用,他可以将多个配置文件,导入合并到一个

假设现有多人开发,每个人开发不同的类,不同的类需要注册在不同的bean中,我们可以利用import将所有的bean.xml合并为一个总得

  • bean.xml
  • bean2.xml
  • bean3.xml
  • ApplicationContext.xml
<import resource="bean2.xml"/>
<import resource="bean3.xml"/>
<import resource="beans.xml"/>

使用时使用总的配置ApplicationContext.xml就可以了

五、依赖注入

5.1、构造器注入

已经说过了

5.2、set注入!【重点】

  • 依赖注入:set注入
    • 依赖:bean对象的创建依赖于容器
    • 注入:bean对象的所有属性,由容器来注入

【环境搭建】

1.复杂类型

package com.LH.pojo;

public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

2.真实测试对象

public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String> card;
    private Set<String> games;
    private Properties info;
    private String wife;

3.beans.xml

<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">

<!--第一种使用普通值注入,vlue-->
    <bean id="student" class="com.LH.pojo.Student">
        <property name="name" value="猪猪猪"/>
    </bean>
</beans>

4.测试

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        Student student = (Student) context.getBean("student");
        System.out.println(student.getAddress());

    }
}

5.完善注册

   <bean id="address" class="com.LH.pojo.Address">
        <property name="address" value="四川"/>
    </bean>

    <bean id="student" class="com.LH.pojo.Student">
        <!--第一种使用普通值注入,vlue-->
        <property name="name" value="猪猪猪"/>
        <!--bean注入,ref-->
        <property name="address" ref="address"/>
        <!--数组-->
        <property name="books">
            <array>
                <value>世界那么大我想去看看</value>
                <value>C++从入门到精通</value>
                <value>考研英语2020</value>
            </array>
        </property>
        <!--List-->
        <property name="hobbys">
            <list>
                <value>唱歌</value>
                <value>画画</value>
                <value>吃饭</value>
            </list>
        </property>
        <!--Map-->
        <property name="card">
            <map>
                <entry key="身份证" value="510xxxxxxxxxxxxxxxx"/>
                <entry key="银行卡" value="155465464564654651"/>
            </map>
        </property>
        <!--Set-->
        <property name="games">
            <set>
                <value>王者荣耀</value>
                <value>LOL</value>
                <value>COC</value>
            </set>
        </property>
        <!--null-->
        <property name="wife">
            <null/>
        </property>
        <!--Properties-->
        <property name="info">
            <props>
                <prop key="driver">小明</prop>
                <prop key="url">201812345678</prop>
                <prop key="username">root</prop>
                <prop key="password">151212</prop>
            </props>
        </property>
    </bean>

5.3拓展方式注入

使用p命名和c命名空间进行注入

官方解释:
在这里插入图片描述

使用:

<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命名空间注入,可以直接注入属性的值:peoperties-->
    <bean id="user" class="com.LH.pojo.User" p:name="猪猪" p:age="21"/>

<!--c命名空间注入,可以通过构造器注入construct-->
    <bean id="user2" class="com.LH.pojo.User" c:name="猪猪2" c:age="18    "/>
</beans>

测试:

@Test
public void Test(){
    ApplicationContext context = new ClassPathXmlApplicationContext("UserBean.xml");
    User user = context.getBean("user2", User.class);
    System.out.println(user);
}

注意点:

p命名和c命名不能直接使用需要导入配置文件

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

5.4、Bean的作用域
在这里插入图片描述

1.单例模式:(Spring默认的)

singleton

<bean id="user2" class="com.LH.pojo.User" c:name="猪猪2" c:age="18" scope="singleton"/>

2.原型模式:每次从容器中get的时候,都会产生一个新的对象

prototype

<bean id="user2" class="com.LH.pojo.User" c:name="猪猪2" c:age="18" scope="prototype"/>

3.其余的 request,session,application只能在web开发中使用!

六、Bean的自动装配

  • 自动装配是Spring满足Bean依赖的一种方式
  • Spring会在上下文中自动寻找,并自动给Bean装配属性

spring中有三种装配方式

  • 在xml中显示配置
  • 在java中显示配置
  • 隐式的自动装配bean

6.1、测试

环境搭建:一个人有两个宠物!

6.2、ByName的自动装配

<!--
byname:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid!
-->
    <bean id="people" class="com.LH.pojo.People" autowire="byName">
        <property name="name" value="猪猪"/>
    </bean>

6.3、ByType

<bean class="com.LH.pojo.Cat"/>
<bean id="pig123" class="com.LH.pojo.Pig"/>

<!--
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid!
byType:会自动在容器上下文中查找,和自己对象属性类型(class)相同的bean!
-->
    <bean id="people" class="com.LH.pojo.People" autowire="byType">
        <property name="name" value="猪猪"/>
    </bean>

6.4、小结:

  • 使用ByName的时候,需要保证所有的bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致!
  • 使用ByType的时候,需要保证所有的bean的class唯一,并且这个bean需要和自动注入的属性的类型一致!id可以省略不写

6.5、 使用注解自动装配

jdk1.5支持注解,spring2.5支持注解

要使用注解须知:

1.导入约束:context

2.配置注解支持: 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/>

</beans>
@Autowired

直接在属性上使用即可! 也可以在set方式上使用!

使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IOC (Spring)容器中存在,且符合名字byType!

@Autowired
private Cat cat;
@Autowired
private Pig pig;
private String name;
<bean id="cat" class="com.LH.pojo.Cat"/>
<bean id="pig" class="com.LH.pojo.Pig"/>
<bean id="people" class="com.LH.pojo.People"/>

如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候、我们可以使用@Qualifier(value=“xxx”)去配合@Autowired的使用,指定一个唯一的bean对象注入!

@Autowired
@Qualifier(value ="cat2")
private Cat cat;
@Autowired
@Qualifier(value ="pig22")
private Pig pig;
private String name;
<bean id="cat1" class="com.LH.pojo.Cat"/>
<bean id="cat2" class="com.LH.pojo.Cat"/>
<bean id="pig1" class="com.LH.pojo.Pig"/>
<bean id="pig22" class="com.LH.pojo.Pig"/>
<bean id="people" class="com.LH.pojo.People"/>

@Resource注解:

	@Resource(name = "cat2")
    private Cat cat;
	@Resource(name = "pig22")
    private Pig pig;
    private String name;

小结:@Resource和@Autowired区别

@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
  @Resource装配顺序
  1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
  2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
  3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
  4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;

@Autowired 与@Resource的区别:

1、 @Autowired与@Resource都可以用来装配bean. 都可以写在字段上,或写在setter方法上。

2、 @Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:

@Autowired()@Qualifier("baseDao")
private BaseDao baseDao;

3、@Resource(这个注解属于J2EE的),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

@Resource(name="baseDao")
private BaseDao baseDao;

推荐使用:@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。这样代码看起就比较优雅。

七、使用注解开发

在spring4之后,要使用注解开发,就必须要保证aop的包导入了

在这里插入图片描述

使用注解一定要导入context约束,增加注解的支持!

7.1、bean

7.2、属性如何注入

// @Value组件等价于    <property name="name" value="猪猪"/>
@Component
public class User {

    @Value("猪猪")
    String name;
   //也可以直接放在方法上面
    @Value("猪猪2")
     public void setName(String name) {
        this.name = name;
    }

7.3、衍生的注解

@component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层

  • dao 【@Repository】
  • serviceo 【@Service】
  • controller 【@Controller】

这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean

7.4、自动装配置

@Autowired :自动装配通过类型,名字
如果Autowired 不能唯一自动装配上属性,则需要通过@Qualifier(value=“xxx”)

@Nullable 字段标记了这个注解,说明这个字段可以为nu77;
@Resource:自动装配通过名字,类型

7.5、作用域

@Scope

7.6、小结

xml与注解:

  • xml 更加万能,适用于任何场 合!维护简单方便
  • 注解不是自己类使用不了,维护相对复杂!
  • xml与注解最佳实践:
    • xml用来管理bean
    • 注解只负责完成属性的注入
    • 我们在使用的过程中,只需要注意一个问题,必须让注解生效,需要开启注解支持
<!--指定要扫描的包,这个包下的注解就会生效-->
    <context:component-scan base-package="com.LH"/>
    <!--注解支持-->
    <context:annotation-config/>

7.3、衍生的注解

@component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层

  • dao 【@Repository】
  • serviceo 【@Service】
  • controller 【@Controller】

这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean

7.4、自动装配置

@Autowired :自动装配通过类型,名字
如果Autowired 不能唯一自动装配上属性,则需要通过@Qualifier(value=“xxx”)

@Nullable 字段标记了这个注解,说明这个字段可以为nu77;
@Resource:自动装配通过名字,类型

7.5、作用域

@Scope

7.6、小结

xml与注解:

  • xml 更加万能,适用于任何场 合!维护简单方便
  • 注解不是自己类使用不了,维护相对复杂!
  • xml与注解最佳实践:
    • xml用来管理bean
    • 注解只负责完成属性的注入
    • 我们在使用的过程中,只需要注意一个问题,必须让注解生效,需要开启注解支持
<!--指定要扫描的包,这个包下的注解就会生效-->
    <context:component-scan base-package="com.LH"/>
    <!--注解支持-->
    <context:annotation-config/>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值