zoukankan      html  css  js  c++  java
  • Spring入门

    1.Spring 简介

    Spring的基础架构起源于2000年早期,它是Rod Johnson在一些成功的商业项目中构建的基础设施

    2002后期,Rod Johnson发布了《Expert One-on-One J2EE Design and Development》一书

    2003年2月Spring框架正式成为一个开源项目,并发布于SourceForge中

    1.2 Spring工作原理

    Spring是一种用JavaBean配置应用程序的方法

    运用SpringIOC,通过setter方法来暴露一个类的任何依赖关系(如一个数据库连接),只要在Spring中进行配置来解决依赖性,不用编写一个数据库连接

    运用Spring AOP 可以解决公共代码重复问题

    1.3 Spring框架简介

    Spring框架

    轻量级

    容器

    开源框架

    用于解决企业应用程序开发复杂性

    一个轻量级的IOC和AOP容器框架

    一个解决了许多J2EE开发中常见的问题的强大框架

    1.4 Spring框架简介

    Spring框架有7个模块, 每个模块都可以单独存在,或者与其他一个或多个模块联合实现

    2.1 Spring Bean 封装机制

    Spring以Bean的方式管理所有的组件,J2EE的全部组件都被视为Bean管理

    Spring负责创建Bean的实例,并管理其生命周期

    Bean在Spring的容器中运行,无须知道Spring容器的存在也可以使用Spring的一些特性

    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <beans xmlns="http://www.springframework.org/schema/beans"
    3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4     xsi:schemaLocation="http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    5     <bean id=“user" class="com.hr.g3.persist.UserVo"
    6         abstract="false" lazy-init="default" autowire="default"
    7         dependency-check="default">
    8     </bean> 
    9 </beans>
    最简单的Spring XML配置文件
     1 <bean
     2 id="beanId"
     3 name ="beanName"
     4 class="beanClass"
     5 parent="parentBean"
     6 abstract="true | false"
     7 scope="prototype|singleton"
     8 lazy-init="true | false | default"
     9 autowire="no | byName | by Type | constructor | auto detect |default">
    10 </ bean>
    Spring XML文件bean节点常见属性

    BeanFactory

    BeanFactory由org.springframework.beans.factory.BeanFactory接口定义

    BeanFactory是工厂模式(Factory pattern)的实现,负责创建和管理bean

    BeanFactory接口包含以下基本方法

    containsBean(String name)

    getBean(String name)

    getBean(String name,Class class)

    getType(String name)

    ApplicationContext

    ApplicationContext是基于BeanFactory之上的,提供了应用程序框架服务,扩展的新功能如下

    提供国际化的支持

    资源访问,如URL和文件

    事件传递

    载入多个配置文件等

    搜索classpath路径,以classpath路径下的applicationContext.xml和bean.xml创建ApplicationContext

    1 ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“applicationContext.xml”);//单个文件
    2 
    3 
    4 BeanFactory beanFactory = new ClassPathXmlApplicationContext(new String[]{“applicationContext.xml”,“bean.xml”}); //多个文件

    按照指定路径下的applicationContext.xml和bean.xml创建ApplicationContext

    BeanFactory beanFactory = 
    new FileSystemXmlApplicationContext(
    new String[]{
    "/WebRoot/WEB-INF/classes/applicationContext.xml",
    "/WebRoot/WEB-INF/classes/bean.xml"});

    ApplicationContext接口的重要方法

     1 (1)containsBean(String name)方法。
     2 //判断Spring容器是否包含ID为 user的Bean
     3 boolean flag=applicationContext.containsBean("user");
     4 
     5 (2)getBean(String name)方法。
     6 //返回ID为 user的Bean
     7 UserVo userBean= (UserVo)applicationContext.getBean("user");
     8 
     9 
    10 (3)getType(String name)方法
    11 //返回:ID为 user 的类型
    12 Class beanType= applicationContext.getType("user");

    3.Spring依赖注入 (非注解)

    设值注入的优点

    如果依赖关系(或继承关系)较为复杂 ,设值注入模式往往更为简洁 有些地方有其局限性

    直观,更加自然

    构造注入的优点

    构造期即创建一个完整、合法的对象

    避免了繁琐的setter方法的编写

    无需担心在调用过程中执行setter方法对组件依赖关系产生破坏

    在构造函数中决定依赖关系的注入顺序

    自动注入

    简化配置文件

    3.1接口与实体类

    1 package cn.yunhe.entity;
    2 
    3 /**
    4  * Created by Administrator on 2017/7/11.
    5  */
    6 public interface Display {
    7     void printDisplayInfo();
    8 
    9 }
    Display(显示器)
     1 package cn.yunhe.entity;
     2 
     3 /**
     4  * Created by Administrator on 2017/7/11.
     5  */
     6 public class Computer {
     7     private MainFrame mainFrame;//主机
     8     private Display display;//显示器接口
     9 
    10     public Computer() {
    11     }
    12 
    13     public Computer(MainFrame mainFrame, Display display) {
    14         this.mainFrame = mainFrame;
    15         this.display = display;
    16     }
    17 
    18     //输出计算机配置信息
    19     public void printComputerInfo(){
    20         System.out.println("计算机配置如下:");
    21         mainFrame.printMainFrameInfo();//输出主机信息
    22         display.printDisplayInfo();//输出显示器信息
    23 
    24     }
    25 
    26     public MainFrame getMainFrame() {
    27         return mainFrame;
    28     }
    29 
    30     public void setMainFrame(MainFrame mainFrame) {
    31         this.mainFrame = mainFrame;
    32     }
    33 
    34     public Display getDisplay() {
    35         return display;
    36     }
    37 
    38     public void setDisplay(Display display) {
    39         this.display = display;
    40     }
    41 }
    Computer
     1 package cn.yunhe.entity;
     2 
     3 /**
     4  * Created by Administrator on 2017/7/11.
     5  */
     6 public class LgDisplay  implements Display{
     7 
     8     //LG显示器
     9     public void printDisplayInfo() {
    10         System.out.println("显示器:LG显示器");
    11     }
    12 }
    LgDisplay
     1 package cn.yunhe.entity;
     2 
     3 /**
     4  * Created by Administrator on 2017/7/11.
     5  */
     6 public class MainFrame {
     7     private String modelType; //型号
     8     //输出主机信息
     9     public void printMainFrameInfo(){
    10         System.out.println("主机型号:"+modelType);
    11     }
    12 
    13     public String getModelType() {
    14         return modelType;
    15     }
    16 
    17     public void setModelType(String modelType) {
    18         this.modelType = modelType;
    19     }
    20 }
    MainFrame
     1 package cn.yunhe.entity;
     2 
     3 /**
     4  * Created by Administrator on 2017/7/11.
     5  */
     6 public class SamSungDisplay implements Display{
     7 
     8     //三星显示器
     9     public void printDisplayInfo() {
    10         System.out.println("显示器:三星显示器");
    11     }
    12 }
    SamSungDisplay
     1 package cn.yunhe.entity;
     2 
     3 import java.util.*;
     4 
     5 /**
     6  * Created by Administrator on 2017/7/11.
     7  */
     8 public class TestBean {
     9     private List list;
    10     private Map map;
    11     private Properties prop;
    12     private Set set;
    13 
    14     public List getList() {
    15         return list;
    16     }
    17 
    18     public void setList(List list) {
    19         this.list = list;
    20     }
    21 
    22     public Map getMap() {
    23         return map;
    24     }
    25 
    26     public void setMap(Map map) {
    27         this.map = map;
    28     }
    29 
    30     public Properties getProp() {
    31         return prop;
    32     }
    33 
    34     public void setProp(Properties prop) {
    35         this.prop = prop;
    36     }
    37 
    38     public Set getSet() {
    39         return set;
    40     }
    41 
    42     public void setSet(Set set) {
    43         this.set = set;
    44     }
    45 }
    TestBean
     1 package cn.yunhe.entity;
     2 
     3 /**
     4  * Created by Administrator on 2017/7/11.
     5  */
     6 public class UserVo {
     7     private int id;
     8     private String name;
     9     private int age;
    10 
    11     public void printInfo(){
    12         System.out.println("姓名:"+name+",年龄:"+age);
    13     }
    14 
    15     public int getId() {
    16         return id;
    17     }
    18 
    19     public void setId(int id) {
    20         this.id = id;
    21     }
    22 
    23     public String getName() {
    24         return name;
    25     }
    26 
    27     public void setName(String name) {
    28         this.name = name;
    29     }
    30 
    31     public int getAge() {
    32         return age;
    33     }
    34 
    35     public void setAge(int age) {
    36         this.age = age;
    37     }
    38 }
    UserVo

    3.2配置文件

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4        xmlns:p="http://www.springframework.org/schema/p"
     5        xmlns:context="http://www.springframework.org/schema/context"
     6        xmlns:aop="http://www.springframework.org/schema/aop"
     7        xsi:schemaLocation="http://www.springframework.org/schema/beans
     8     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     9     http://www.springframework.org/schema/context
    10     http://www.springframework.org/schema/context/spring-context-3.0.xsd
    11     http://www.springframework.org/schema/aop
    12     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    13 
    14     <context:component-scan base-package="cn.yunhe.entity"/>
    15     <bean id="user" class="cn.yunhe.entity.UserVo"/>
    16     <bean id="mainFrame" class="cn.yunhe.entity.MainFrame">
    17         <property name="modelType" value="三星高配主机"/>
    18     </bean>
    19     <bean id="lg" class="cn.yunhe.entity.LgDisplay"/>
    20     <bean id="samsung" class="cn.yunhe.entity.SamSungDisplay"/>
    21 
    22     <!--设值注入是指通过setter方法传入被调用者的实例-->
    23     <!--<bean id="computer" class="cn.yunhe.entity.Computer">
    24         <property name="mainFrame" ref="mainFrame"/>
    25         <property name="display" ref="lg"/>
    26     </bean>-->
    27     <!--构造注入是指通过构造方法完成依赖关系的注入-->
    28     <bean id="computer2" class="cn.yunhe.entity.Computer">
    29         <constructor-arg index="0" ref="mainFrame"/>
    30         <constructor-arg index="1" ref="samsung"/>
    31     </bean>
    32 
    33     <!--Spring容器可以自动注入(autowire)相互协作bean之间的关联关系-->
    34     <!--no : 不适用自动的装配,必须通过ref元素指定依赖。这是默认设置。
    35             由于显式指定协作者可以使配置更灵活、更清晰,因此对于较大的
    36             部署配置,推荐采用该设置。-->
    37     <!--byName :根据属性名自动装配。此选项将检查容器并根据名字查找与属
    38                 性完全一致的bean,并将其与属性自动装配-->
    39     <!--byType :如果容器中存在一个与指定属性类型相同的bean,那么将与该
    40                 属性自动装配。如果存在多个该类型的bean,那么将会抛出异
    41                 常,并指出不能使用byType方式进行自动装配。若没有找到相
    42                 匹配的bean,则属性不会被设置。-->
    43     <bean id="computer" class="cn.yunhe.entity.Computer" autowire="byName">
    44         <property name="display" ref="lg"/>
    45     </bean>
    46 
    47     <!--集合属性-->
    48     <bean id="testBean" class="cn.yunhe.entity.TestBean">
    49         <property name="list">
    50             <list>
    51                 <value>aaa</value>
    52                 <value>bbb</value>
    53                 <value>ccc</value>
    54             </list>
    55         </property>
    56         <property name="map">
    57             <map>
    58                 <entry key="k1" value="v1"/>
    59             </map>
    60         </property>
    61         <property name="prop">
    62             <props>
    63                 <prop key="k1" >str1</prop>
    64             </props>
    65         </property>
    66         <property name="set">
    67             <set>
    68                 <value>ddd</value>
    69                 <value>eee</value>
    70             </set>
    71         </property>
    72     </bean>
    73 </beans>
    applicationContext.xml

    3.3 测试类

     1 package cn.yunhe.demo;
     2 
     3 import cn.yunhe.entity.Computer;
     4 import cn.yunhe.entity.TestBean;
     5 import cn.yunhe.entity.UserVo;
     6 import org.junit.Before;
     7 import org.junit.Test;
     8 import org.springframework.context.ApplicationContext;
     9 import org.springframework.context.support.ClassPathXmlApplicationContext;
    10 
    11 import java.util.List;
    12 
    13 /**
    14  * Created by Administrator on 2017/7/11.
    15  */
    16 public class Demo {
    17 
    18     ApplicationContext applicationContext =null;
    19     @Before
    20     public void init(){
    21         //以classpath路径下的applicationContex.xml创建Spring容器
    22         applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");
    23     }
    24 
    25     @Test
    26     public void test1(){
    27         //从Spring容器中获取ID 为user的Bean
    28         UserVo user=applicationContext.getBean("user",UserVo.class);
    29         //封装姓名和年龄
    30         user.setName("张三丰");
    31         user.setAge(100);
    32         //输出该bean的信息
    33         user.printInfo();
    34     }
    35 
    36     @Test//Spring的设值注入方式    //自动注入也有用这个例子
    37     //设值注入是指通过setter方法传入被调用者的实例
    38     public void test2(){
    39       Computer computer=  applicationContext.getBean("computer", Computer.class);
    40         computer.printComputerInfo();
    41     }
    42 
    43     @Test//Spring的构造注入方式
    44     //构造注入是指通过构造方法完成依赖关系的注入
    45     public void test3(){
    46         Computer computer=applicationContext.getBean("computer2",Computer.class);
    47         computer.printComputerInfo();
    48     }
    49 
    50     @Test//集合属性
    51     public void test4(){
    52         TestBean testBean=applicationContext.getBean("testBean",TestBean.class);
    53         List<String>list = testBean.getList();
    54         for (String str:list){
    55             System.out.println(str);
    56         }
    57     }
    58 
    59 }
    Demo

     4.注解实现Spring注入

    @Component 注解配置bean @Component注解唯一的一个可选参数是value,用于指定bean的名称(即id值,所以必须是唯一的)

    1 @Component(”computer”)
    2 public class Computer { }
    3 @Component
    4 public class MainFrame {}
    5 @Component
    6 public class SamSungDisplay implements Display {}
    7 @Component
    8 public class LgDisplay implements Display {}

     只需在配置文件中配置以下代码     扫描@Component标注的类

    1 <context:component-scan 
    2 base-package="s3spring.ch1.annotation.computer"/>
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    
    //从容器获取bean
    Computer c = ac.getBean(Computer.class);

    使用 @Scope注解配置bean 的作用域

    @Scope定义bean的作用域,singleton表示在Spring loC容器中一个bean的定义对应一个对象实例,Spring使用单例模式获取实例

         prototype 表示一个bean定义对应多个对象实例,即非单例模式,常称作多例

    1 @Component
    2 @Scope(value="prototype")
    3 public class Computer { …… }

    使用@Autowired注解  

      可以对类成员变量、方法及构造函数进行标注,以完成自动装配依赖的工作

       @Autowired 默认按 byType 自动注入

    1 @Component
    2 @Scope("prototype")
    3 public class Computer {
    4 @Autowired
    5 private MainFrame mainFrame;// 主机
    6 @Autowired
    7 private Display display;// 显示器接口
    8 ……

    多个bean导致的创建bean失败的问题

    把属性名称做为依赖bean名称

    @Qualifier 注解明确指定依赖bean的名称(就是显示器接口被多个类实现,导致使用该接口时不知道调那个类,就需要在这里声明一下)

     1 @Component
     2 @Scope("prototype")
     3 public class Computer {
     4 @Autowired
     5 private MainFrame mainFrame;// 主机
     6 @Autowired
     7 @Qualifier("samSungDisplay")//表明是用的三星的
     8 private Display display;// 显示器接口
     9     ……
    10 }

    注解的运行流程

    1.首先根据属性的类型在Spring 应用容器中查找类型匹配的bean

    2.如果没有类型匹配的bean,抛出BeanCreationException;如果只有一个,则注入依赖,完成自动装配;如果不只一个,则继续执行步骤3;

    3.如果通过 @Qualifier指定了bean 名称,则从所有符合类型的bean中返回指定的bean,完成自动装配;如果没有通过 @Qualifier制定bean 名称,则通过反射技术获取当前属性的名称作为bean 名称返回指定的bean,完成自动装配;

     

    使用@Resource注解注入依赖   

    @Resource 默认按 byName 自动注入    用法与上边使用@Autowire相同

     1 @Component
     2 @Scope("prototype")
     3 public class Computer {
     4     @Resource
     5     private MainFrame mainFrame;//采用属性名称作为依赖bean的名称
     6  
     7     @Resource(name="samSungDisplay")
     8     private Display display;// 采用@name参数值作为依赖bean的名称
     9      ……
    10 }

    使用JSR-250规范定义的注解

    @PostConstruct 和 @PreDestroy

    @PostConstruct 注解的方法将在类实例化后调用,

    @PreDestroy注解的方法将在类销毁之前调用 ConfigurableApplicationContext close方法

    1 @PostConstruct
    2 public void postConstruct1(){
    3          System.out.println("执行postConstruct1");
    4 }
    5  
    6 @PreDestroy
    7 public void preDestroy1(){
    8          System.out.println("执行preDestroy1"); 
    9 }
  • 相关阅读:
    【ICLR2018】Mixup 解读
    MobileNetV2 解读
    MobileNetV1 解读
    AdaIN 解读
    心灵奇旅
    SA-Net: Shuffle Attention for Deep Convolutional Neural Networks
    ShuffleNet V1 解读
    情人节看《唐探3》
    拆弹人
    内卷常态下的就业烦恼
  • 原文地址:https://www.cnblogs.com/liuyingke/p/7152550.html
Copyright © 2011-2022 走看看