美文网首页
Spring学习笔记

Spring学习笔记

作者: __Andy__ | 来源:发表于2018-12-10 16:17 被阅读14次

1Spring

Spring是一个在工作当中经常听见的一个词,但是什么是Spring呢?
感谢以下作者
https://www.yiibai.com/spring/spring-tutorial-for-beginners.html
https://www.cnblogs.com/jiangzhaowei/p/9622543.html
https://www.cnblogs.com/wuchanming/p/5426746.html
在网上找了Spring的教程,如下图

spring.png

IoC Container:

这是最重要的,也是最基础的, Spring的基础。
它的作用是配置和Java对象的生命周期管理
DAO, ORM, AOP, WEB: 该模块可用于将工具或框架集成到了Spring

1.1. IOC Inversion of Control 控制反转

.png

2.1 名词定义

IOC: 控制反转,将类的对象的创建交给Spring类管理创建.
DI: 依赖注入,将类里面的属性在创建类的过程中给属性赋值.
DI和IOC的关系: DI不能单独存在,DI需要在IOC的基础上来完成.

1.2 Spring 核对包:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>${spring.version}</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>${spring.version}</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>${spring.version}</version>
</dependency>

2 Spring 容器装配Bean

2.1 基于xml配置Bean
2.2 使用注解定义Bean
2.3 基于java类提供Bean定义信息

2.1 Spring 容器装配Bean-基于xml配置Bean

bean.xml

xml配置文件的方式对bean进行声明和管理

#com.Andy.spring.user
   <bean id="user" name="#user1" class="com.Andy.spring.user"></bean>  
   <bean id="userdao" class="com.Andy.spring.userdaoimpl"></bean>

每一个bean标签都代表着需要被创建的对象并通过property标签可以为该类注入其他依赖对象
通过这种方式Spring容器就可以成功知道我们需要创建那些bean实例
然后通过ClassPathXmlApplicationContext去加载spring的配置文件
接着获取想要的实例bean并调用相应方法执行


Spring加载xml.png

依赖注入
属性注入
构造函数注入
工厂方式注入

2.1.1 加载Spring-XML配置文件的多种方式

对于ClassPathXmlApplicationContext默认加载classpath路径下的文件,只需指明对应文件的classpath路径即可,如果存在多个配置文件,则只需分别传递即可;
ClassPathXmlApplicationContext是一个可以接收可变参数的构造函数。
除了ClassPathXmlApplicationContext,还有一种读取方式就是使用FileSystemXmlApplicationContext,它默认为项目工作路径 即项目的根目录

 ##默认查找classpath路径下的文件 
   ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring/spring-ioc.xml");
 ##多文件
    ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring/spring-ioc.xml","spring/spring-ioc2.xml",.....);
 ##默认为项目工作路径 即项目的根目录
    FileSystemXmlApplicationContext applicationContext=new FileSystemXmlApplicationContext("/src/main/resources/spring/spring-ioc.xml");
 ##读取classpath下的文件
   FileSystemXmlApplicationContext applicationContext=new FileSystemXmlApplicationContext("classpath:spring/spring-ioc.xml");
 ##使用前缀file 表示的是文件的绝对路径
  ApplicationContext applicationContext = new FileSystemXmlApplicationContext("file:D:/app.spring.xml");
 ##多文件与ClassPathXmlApplicationContext相同
  ApplicationContext applicationContext = new FileSystemXmlApplicationContext("file:D:/app.spring.xml","file:D:/app.spring1.xml",......);

2.2 使用注解定义Bean

Spring容器成功启动的三大要件分别是:Bean定义信息、Bean实现类以及Spring本身。如果采用基于XML的配置,Bean定义信息和Bean实现类本身是分离的,而采用基于注解的配置方式时,Bean定义信息即通过在Bean实现类上标注注解实现。

给一个类定义@Component注解
等于
<bean id="xxx" class="xxx"/>

2.2.1 Spring 注解

1、@controller 控制器(注入服务)
2、@service 服务(注入dao)
3、@repository dao(实现dao访问)
4、@component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>)
@Component,@Service,@Controller,@Repository注解的类,并把这些类纳入进spring容器中管理。

下面写这个是引入component的扫描组件 
<context:component-scan base-package=”com.x”>    
其中base-package为需要扫描的包(含所有子包) 
       1、@Service用于标注业务层组件 
       2、@Controller用于标注控制层组件(如struts中的action) 
       3、@Repository用于标注数据访问组件,即DAO组件. 
       4、@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。    
           @Service 
           public class UserServiceImpl implements UserService { } 
           @Repository 
           public class UserDaoImpl implements UserDao { } 
            getBean的默认名称是类名(头字母小写),如果想自定义,可以@Service(“***”) 这样来指定,这种bean默认是单例的,如果想改变,可以使用@Service(“beanName”) @Scope(“prototype”)来改变。
            可以使用以下方式指定初始化方法和销毁方法(方法名任意):
           @PostConstruct public void init() { } 

2.2.2 Spring 注解注入XML配置
Spring提供了一个context的命名空间,它提供了通过扫描类包以应用注解定义Bean的方式
1.在xml中声明context的命名空间
如下图

<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 
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd"
         >

2.在xml中增加扫描类应用注解定义的Bean
1完成后,
可通过context命名空间的component-scan的base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里的所有类,并从类的注解信息中获取Bean的定义信息。

#扫描基类包中所有的类(包获子包):
#com.Andy.spring.anno
< context:component-scan base-package=" com.Andy.spring.anno" / >

如果仅希望扫描特定的类而非基包下的所有类,可以使用resource-pattern属性过滤特定的类,如下所示:

#指定类:
#com.Andy.spring.anno
< context:component-scan base-package=" com.Andy.spring" resource-pattern="anno/*.class"/ >

这里我们将基类包设置为xx.xx,默认情况下resource-pattern属性的值为"/.class",即基类包里的所有类。这里我们设置为"anno/.class",则Spring仅会扫描基包里anno子包中的类。

2.3 基于java类提供Bean定义信息

注解式主要需要引用context包

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>${spring.version}</version>
</dependency>
通过java代码方式加载Bean.png

如上图:
Spring注解加载有3步

1.spring-context包引入。
2.配置Bean的类必须要使用@Configuration注解,注解@Configuration等价于<beans>标签,在该类中,@Bean等价于<bean>标签。
3.使用AnnotationConfigApplicationContext进行加载

3. Spring Bean注入

Bean注入的方式有两种,
一种是在XML中配置,此时分别有属性注入、构造函数注入和工厂方法注入;
另一种则是使用注解的方式注入 @Autowired,@Resource,@Required

依赖注入定义

所谓的依赖注入,其实是当一个bean实例引用到了另外一个bean实例时spring容器帮助我们创建依赖bean实例并注入(传递)到另一个bean中,如上述案例中的AccountService依赖于AccountDao,Spring容器会在创建AccountService的实现类和AccountDao的实现类后,把AccountDao的实现类注入AccountService实例中,下面分别介绍setter注入和构造函数注入。

3.1.1 属性注入

属性注入即通过setXxx()方法注入Bean的属性值或依赖对象,由于属性注入方式具有可选择性和灵活性高的优点,因此属性注入是实际应用中最常采用的注入方式。

属性注入要求Bean提供一个默认的构造函数,并为需要注入的属性提供对应的Setter方法。Spring先调用Bean的默认构造函数实例化Bean对象,然后通过反射的方式调用Setter方法注入属性值。
示例:

package com.Andy.spring;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Account {
    private String name;
    private String pwd;
    private List<String> citys;
    private Set<String> friends;
    private Map<Integer,String> books;
    public String getName() {
        return name;
    }
    public String getPwd() {
        return pwd;
    }
    public List <String> getCitys() {
        return citys;
    }
    public Set <String> getFriends() {
        return friends;
    }
    public Map <Integer, String> getBooks() {
        return books;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public void setCitys(List<String> citys) {
        this.citys = citys;
    }
    public void setFriends(Set<String> friends) {
        this.friends = friends;
    }
    public void setBooks(Map<Integer, String> books) {
        this.books = books;
    }
}

在XML中的配置

  <!-- setter通过property 注入属性值,普通类型使用value -->
    <bean id="account" scope="prototype" class="ioc1.Account" >
        <property name="name" value="I am SpringIOC1" />
        <property name="pwd" value="123" />
        <!-- 注入map -->
        <property name="books">
            <map>
                <entry key="10" value="CoreJava">
                </entry>
                <entry key="11" value="JavaWeb">
                </entry>
                <entry key="12" value="SSH2">
                </entry>
            </map>
        </property>
        <!-- 注入set -->
        <property name="friends">
            <set>
                <value>小红</value>
                <value>小黄</value>
                <value>小白</value>
            </set>
        </property>
        <!-- 注入list -->
        <property name="citys">
            <list>
                <value>北京</value>
                <value>上海</value>
                <value>深圳</value>
            </list>
        </property>
    </bean>

3.1.2 构造方法注入

public class LogonService implements BeanNameAware{
    public LogonService(){}
    //构造方法
    public LogonService(LogDao logDao, UserDao userDao) {
        this.logDao = logDao;
        this.userDao = userDao;
    }
...

XML配置

    <bean id="logDao" class="com.Andy.spring.LogDao"/>
    <bean id="userDao" class="com.Andy.spring.UserDao"/>
    <bean class="com.Andy.spring.LogonService">
        <constructor-arg  ref="logDao"></constructor-arg>
        <constructor-arg ref="userDao"></constructor-arg>
    </bean>

当一个方法有多个同类型参数时,在<constructor-arg>标签中存在一个index的属性,通过index属性可以告诉spring容器传递的依赖参数的顺序,下面的配置将会令Spring容器成功找到第一个构造函数并调用创建user实例。

<bean id="user" class="com.Andy.spring.UserDao >
    <constructor-arg index="0" value="Jack"/>
    <constructor-arg index="1" value="26"/>
</bean>

3.1.3 工厂方法注入

3.1.3.1 非静态工厂方法:

有些工厂方法是非静态的,即必须实例化工厂类后才能调用工厂放。

public class CarFactory {
   public Car createHongQiCar(){
       Car car = new Car();
       car.setBrand("红旗CA72");
       return car;
   }
}

xml

    <!-- 工厂方法-->
    <bean id="carFactory" class="com.Andy.spring.CarFactory" />
    <bean id="car5" factory-bean="carFactory" factory-method="createHongQiCar">
    </bean>
3.1.3.2 静态工厂方法

很多工厂类都是静态的,这意味着用户在无须创建工厂类实例的情况下就可以调用工厂类方法,因此,静态工厂方法比非静态工厂方法的调用更加方便。

...
   public static Car createCar(){
       Car car = new Car();
       return car;
   }
...

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" 
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="car6" class="com.Andy.spring.CarFactory"
        factory-method="createCar"></bean>
</beans>

3.2使用注解的方式注入

3.2.1 使用@Autowired进行自动注入

//todo

3.2.2 使用@Autowired的required属性

//todo

3.2.3 使用@Qualifier指定注入Bean的名称

//todo

3.2.4 对类方法进行标注

//todo

3.2.5 对标准注解的支持

//todo

3.2.6 关于Autowired和@Resource

//todo

3.2.7 让@Resource和@Autowired生效的几种方式

//todo

Spring的自动装配有三种模式:
byTpye(根据类型)
byName(根据名称)
constructor(根据构造函数)。

相关文章

网友评论

      本文标题:Spring学习笔记

      本文链接:https://www.haomeiwen.com/subject/udwthqtx.html