spring之再学习(1)

Spring 4.x 官方博客

Spring Framework 是一个开源的Java/Java EE全功能栈(full-stack)的应用程序框架,以Apache许可证形式发
布。
该框架基于 Expert One-on-One Java EE Design and Development(ISBN 0-7645-4385-7)一书中的代码,最
初由Rod Johnson和Juergen Hoeller等开发。
Spring Framework提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量
的属性文件和帮助类。

Sping体系

image

2 Spring 快速入门

  • 2.1 编写流程
    maven依赖或者下载jar包
    <!--spring的依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
  • 2.2 SayHello 实现
★Spring核心开发包
  • spring-core-3.2.2.RELEASE.jar
  • 包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心。
  • spring-beans-3.2.2.RELEASE.jar
  • 所有应用都要用到的,它包含访问配置文件、创建和管理bean
  • 以及进行Inversion of Control(IoC) / Dependency Injection(DI)操作相关的所有类
2.2.2 编写业务类
/**
 * Created by wanggs on 2017/7/7.
 */
public class SayHello {

    public void sayHello() {
        System.out.println("Spring4X......");
    }
}
2.2.3 传统方式创建实例
/**
 * Created by wanggs on 2017/7/7.
 */
public class SayHelloTest {
    public static void main(String[] args) {
        //传统方式创建实例(对象)
        SayHello sayHello = new SayHello();
        sayHello.sayHello();
    }
}
2.2.4 Spring IoC控制反转创建实例
  • 编写配置文件( Spring 容器)
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--id: bean 在容器的名称不能重复 -->
    <!--class: 放入spring容器的包的完全限定名-->
    <bean id="sayHello" class="com.wanggs.pojo.SayHello"> </bean>
</beans>

  • 从spring容器获得对象实例
package com.wanggs.pojo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by wanggs on 2017/7/7.
 */
public class SayHellTest {
    public static void main(String[] args) {

        //读取配置文件,使用spring 控制反转,交予spring创建对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //"sayHello"-->>即配置文件 (id: bean 在容器的名称)
        SayHello sayHello = (SayHello) applicationContext.getBean("sayHello");

        sayHello.sayHello();
        
        //结果: Spring4X......
    }
}

IoC解释

IoC Inverse of Control 反转控制的概念,就是将原本在程序中手动创建HelloService对象的控制权,交由Spring框架管理,简单说,就是创建HelloService对象控制权被反转到了Spring框架
  • 2.2.5 传统方式设置内容 注意:加了一个name属性
/**
 * Created by wanggs on 2017/7/7.
 */
public class SayHelloTest {
    public static void main(String[] args) {
        //传统方式创建实例(对象)
        SayHello sayHello = new SayHello();
        sayHello.setName("tom");//手动设置值
        sayHello.sayHello();
    }
}
  • 2.2.6 Spring DI 设置字段内容
编写配置文件
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--id: bean 在容器的名称不能重复 -->
    <!--class: 放入spring容器的包的完全限定名-->
    <bean id="sayHello" class="com.wanggs.pojo.SayHello">
    <!--spring设置-->
        <property name="name" value="tom"/>
    </bean>
</beans>


package com.wanggs.pojo;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by wanggs on 2017/7/7.
 */
public class SayHellTest {
    public static void main(String[] args) {

        //读取配置文件,使用spring 控制反转,交予spring创建对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //"sayHello"-->>即配置文件 (id: bean 在容器的名称)
        SayHello sayHello = (SayHello) applicationContext.getBean("sayHello");
        sayHello.setName("tom");
        sayHello.sayHello();
        
        //结果: Spring4X......
    }
}

new一个对象即IOC(<bean>) 对象的属性设置即DI(property)

DI解释

> DI:Dependency Injection 依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件。
    getBean("helloService")从spring容器中获得指定名称对象的实例时,通过此设置<property name="info" value="传智播客"></property> 相当于执行 servcie.setInfo("传智播客");

再来一个例子

3.1 目标类
  • 创建BookService接口和实现类
  • 创建BookDao接口和实现类
  • 将dao和service配置 xml文件
  • 使用api测试
3.1.1 dao

/**
 * Created by wanggs on 2017/7/7.
 */
public interface BookDao {
    public abstract void addBook();
}


//Dao的实现类
/**
 * Created by wanggs on 2017/7/7.
 */
public class BookDaoImpl implements BookDao {
    public void addBook() {
        System.out.println("DI add Book");
    }
}

3.1.2 service

/**
 * Created by wanggs on 2017/7/7.
 */
public interface BookService {
    public abstract void saveBook();
}

// BookService的实现类
/**
 * Created by wanggs on 2017/7/7.
 */
public class BookServiceImpl implements BookService{

    //之前的方式 接口 = 实现类;(多态)
    //spring: 接口+set方法
    private BookDao bookDao;
    public void setBookDao(BookDao bookDao ){
        this.bookDao = bookDao;
    }
    public void saveBook() {
        this.bookDao.addBook();
    }
}

3.2 配置文件
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--id: bean 在容器的名称不能重复 -->
    <!--class: 放入spring容器的包的完全限定名-->
    <bean id="sayHello" class="com.wanggs.pojo.SayHello">
        <property name="name" value="tom"/>
    </bean>

    <!--property 用于属性注入
        name: 属性的名字==>>private BookDao bookDao;
        ref: 引用另一个bean的id
    -->
    <bean id="bookService" class="com.wanggs.service.impl.BookServiceImpl">
        <property name="bookDao" ref="bookDao"/>
    </bean>
    <bean id="bookDao" class="com.wanggs.dao.impl.BookDaoImpl"/>
</beans>

3.3 测试
/**
 * Created by wanggs on 2017/7/7.
 */
public class BookServiceTest {
    public static void main(String[] args) {
        // 读取配置文件,使用spring控制反转交给spring创建对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        // "bookService"-->>即配置文件 (id: bean 在容器的名称)
        BookService bookService = (BookService) applicationContext.getBean("bookService");
        bookService.saveBook();
    }
    //结果:  DI add Book

}

采用p命名配置


<?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-4.0.xsd">
    <bean id="car" class="com.smart.Car"
          init-method="myInit"
          destroy-method="myDestory"
          p:brand="红旗CA72"
          p:maxSpeed="200"
            />

    <bean id="customAutowireConfigurer"
          class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
        <property name="customQualifierTypes">
            <set>
                <value>test.FineQualifier</value>
            </set>
        </property>
    </bean>
    <!-- bean id="car" class="com.smart.beanfactory.Car"
    init-method="myInit"
    destroy-method="myDestory"
    p:brand="红旗CA72"/ -->

</beans>

bean的继承

Spring IOC--Bean的装配(使用注解定义Bean)

概述

在spring中,不管是使用xml还是使用注解,实质上都是为spring容器提供bean的定义信息。而spring容器能够成功启动的三大重要因素是:Bean定义信息、Bean实现类、以及spring本身。如果采用XML配置Bean,那么Bean实现类和Bean定义信息是分离的,如果是用注解,那么Bean的定义信息和实现类都是在一起的,表现在Bean实现类的注解上。

下面是一个简单的dao层的bean注解配置:

package cn.qing.spring.dao;  
  
import org.springframework.stereotype.Component;  
  
@Component("userDao")  
public class UserDao {  
  
}  
在UserDao中使用@Component注解对其进行标注,它会被Spring容器识别,然后自动转换成能被容器管理的Bean。它等效于一下的XML配置:
<bean id="userDao" class="cn.qing.spring.dao.UserDao"/>  

除了@Component注解外,Spring还提供了3个功能和@Component基本等效的注解,它们分别用于对DAO、service、及web层的controller进行注解,也称这些注解为Bean的泛型注解。

1.@Repository:用于对dao实现类进行标注。
2.@Service:用于对service层实现类进行标注。
3.@Controller:用于对web的控制层实现类进行标注。

之所以在@Component注解之外又定义3个注解,是为了让注解类本身的用途清晰化。此外spring将赋予它们特殊的功能,所以推荐使用特别的注解标注特定的Bean.
只是在Bean的实现类上添加上以上注解还是不够的,spring并不会自动扫描出这些带注解的类并将其转换成Bean,所以需要在spring的配置文件中配置spring需要扫描的包,使用下面的<context:component-scan />标签进行配置:

<!-- 在使用注解时,在此配置spring要扫描加载的bean的base package -->  
    <context:component-scan base-package="cn.qing.spring"/>
自动装配Bean:
@Repository("userDao")  
public class UserDao {  
  
    @Autowired  
    private PersonInfo personInfo;  
      
    public void printPersonInfo()  
    {  
        System.out.println("personInfo:"+personInfo.toString());  
    }  
上面的personInfo对象是使用@Autowired注解进行注入。使用@Autowired注解进行bean属性的自动注入,等同于下面的XML配置:
<property name="personInfo" ref="personInfo"/> 

使用java类的配置信息启动spring容器

1. 直接通过@Configuration类启动Spring容器

代码
// http://blog.csdn.net/qq_33665647/article/details/53219979

// 1.将一个POJO标注为定义Bean的配置类
@Configuration
public class AppConf {
    // 2.以下两个方法定义了,两个bean 并提供了Bean的实例化逻辑
    @Bean
    public UserDao userDao(){
       return new UserDao();    
    }
    
    @Bean
    public LogDao logDao(){
        return new LogDao();
    }

    // 3.定义了LogonService 的Bean
    @Bean
    public LogonService logonService(){
        LogonService logonService = new LogonService();
        // 将2.和3.定义的bean注入到定义了LogonService Bean中
        logonService.setLogDao(logDao());
        logonService.setUserDao(userDao());
        return logonService;
    }
}
  • 1.中,在AppConf类中定义处标注了@Configuaration注解,说明这个类可用于为Spring提供Bean的定义信息,该类的方法可标注@Bean注解,Bean的类型由方法返回@Bean(name="userDao")


一下XML与上面等效
 <bean id="userDao" class="com.smart.conf.UserDao"/>
 <bean id="logDao" class="com.smart.conf.LogDao"/>
 <bean id="logonService" class="com.smart.conf.LogonService">
 <property name="userDao" ref="userDao"/>
 <property name="logDao" ref="logDao"/>
 </bean>

完整代码
public class LogonService {

    private LogDao logDao;
    private UserDao userDao;
    public LogDao getLogDao() {
        return logDao;
    }
    public void setLogDao(LogDao logDao) {
        this.logDao = logDao;
    }
    public UserDao getUserDao() {
        return userDao;
    }
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    
    public void printHelllo(){
        System.out.println("hello!");
    }
    
}


package com.smart.conf;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConf {
    @Bean
    public UserDao userDao(){
       return new UserDao();    
    }
    
    @Bean
    public LogDao logDao(){
        return new LogDao();
    }
    
    @Bean
    public LogonService logonService(){
        LogonService logonService = new LogonService();
        logonService.setLogDao(logDao());
        logonService.setUserDao(userDao());
        return logonService;
    }
}

测试
package com.smart.conf;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class JavaConfigTest {
    public static void main(String[] args) {
        
//1.通过构造函数加载配置类     
        ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConf.class);
        LogonService logonService = ctx.getBean(LogonService.class);
        logonService.printHelllo();
        // 输入出 : hello!

//2.通过编码方式注册配置类
    // AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
     //ctx.register(DaoConfig.class);
    // ctx.register(ServiceConfig.class);
     //ctx.refresh();

//3.通过XML组装@Configuration配置类所提供的配置信息
//       ApplicationContext ctx = new ClassPathXmlApplicationContext("com/smart/conf/beans2.xml");

//4.通过@Configuration组装XML配置所提供的配置信息
//       ApplicationContext ctx = new AnnotationConfigApplicationContext(LogonAppConfig.class);

        //5.@Configuration的配置类相互引用
/*       ApplicationContext ctx = new AnnotationConfigApplicationContext(DaoConfig.class,ServiceConfig.class);
         LogonService logonService = ctx.getBean(LogonService.class);
         System.out.println((logonService.getLogDao() !=null));
         logonService.printHelllo();  */
    }
}

任何标注@Configuration的类,就相当于标注@Component注解

其他写法

@Configuration
public class DaoConfig {
    
    
    @Bean(name="")
    public UserDao userDao(){
        return new UserDao();
    }
    
    @Scope("prototype")
    @Bean
    public LogDao logDao(){
        return new LogDao();
    }
}


@Configuration
@Import(DaoConfig.class)
public class ServiceConfig {
    
    @Autowired
    private DaoConfig daoConfig;
    
    @Bean
    public LogonService logonService(){
        LogonService logonService = new LogonService();
        System.out.println(daoConfig.logDao() == daoConfig.logDao());
        logonService.setLogDao(daoConfig.logDao());
        logonService.setUserDao(daoConfig.userDao());
        return logonService;
    }
}

不同方式配置比较

1.

2.

3.

4.
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,596评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,733评论 6 342
  • 来源:关于Spring IOC (DI-依赖注入)你需要知道的一切作者:zejian Dao层(AccountDa...
    杨井阅读 5,324评论 0 27
  • 集中精力打起精神写一篇呢,还是跟自己说一声“算了吧,不写了”,后者远远比前者容易做到啊,可是前者的价值远远高于后者...
    天外来客人阅读 181评论 0 0
  • 一杯白酒下,肚嘴里吐出一句脏话,明天就是市长请我吃饭都不在喝一滴酒,说这话的是我一哥们,正天说戒酒喝酒伤身之类的话...
    念追忆loveing阅读 471评论 0 2