1 Star 1 Fork 0

花开自相依丶 / SpringBootDemo

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
README.md 15.31 KB
一键复制 编辑 原始数据 按行查看 历史
花开自相依丶 提交于 2018-02-05 16:25 . 更新 README.md

(启动该项目需要连接mysql和redis)

基于Maven构建的SpringBoot项目,包括Spring框架的学习

Spring框架结构图

Spring框架图

1)核心容器(Core Container) Spring-Core:核心工具类,Spring其他模块大量使用Spring-Core。 Spring-Beans:Spring定义Bean的支持。 Spring-Context: 运行时Spring容器。 Spring-Context-Support:Spring容器对第三方包的集成支持。 Spring-Expression:使用表达式语音在运行时查询和操作对象。

2)AOP Spring-AOP:基于代理的AOP支持。 Spring-Aspects:基于AspectJ的AOP支持。

3)消息(Messaging) Spring-Messaging:对消息架构和协议的支持。

4)Web Spring-Web:提供基础的Web集成功能,在Web项目中提供Spring容器。 Spring-WebMvc:提供基于Servlet的SpringMVC。 Spring-WebSocket:提供WebScoket功能。 Spring-WebMvc-Portlet:提供Portlet环境支持。

5)数据访问/集成(Data Access/Integration) Spring-JDBC:提供以JDBC访问数据库的支持。 Spring-TX:提供编程式事务和声明式事务的支持。 Spring-ORM:提供对对象/关系映射技术的支持。 Spring-OXM:提供对对象/xml映射技术的支持。(配置的映射) Spring-JMS:提供对JMS的支持。(java消息服务)

声明Bean的注解: @Component组件,没有明确的角色。 @Service在业务逻辑层(Service层)使用。 @Repository在数据访问层(dao层)使用。 @Controller在表现层(MVC--->SpringMVC)使用。

SpringIOC

Spring 控制反转(Spring-IOC): 具体实现是利用Spring依赖注入(SpringDI), 依赖注入是值容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身辅助自己创建对象和解决自己的依赖。依赖注入的目的是为了解耦。 可以使用注解方式 和JavaConfig方式配置DI的Bean。 详细配置方式 请见:https://git.oschina.net/os_val/SpringBootDemo.git 其中的Spring DI包。

Spring-AOP

AOP:面向切面编程,相当于OOP的面向对象编程。 Spring的AOP目的是为了解耦,AOP可以使一组类共享相同的行为。 AOP它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于可操作性和可维护性。 使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

AOP核心概念 1、横切关注点 对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点 2、切面(aspect) 类是对物体特征的抽象,切面就是对横切关注点的抽象 3、连接点(joinpoint) 被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器 4、切入点(pointcut) 对连接点进行拦截的定义 5、通知(advice) 所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类 6、目标对象 代理的目标对象 7、织入(weave) 将切面应用到目标对象并导致代理对象创建的过程 8、引入(introduction) 在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段

Spring对AOP的支持 Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为: 1、默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了 2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB AOP编程其实是很简单的事情,纵观AOP编程,程序员只需要参与三个部分: 1、定义普通业务组件 2、定义切入点,一个切入点可能横切多个业务组件 3、定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作 所以进行AOP编程的关键就是定义切入点和定义增强处理,一旦定义了合适的切入点和增强处理,AOP框架将自动生成AOP代理,即:代理对象的方法=增强处理+被代理对象的方法。

Spring支持AspectJ的注解式切面编程。 (1)使用@Aspect声明是一个切面。 (2)使用@After、@Before、@Around定义建言(advice),可直接将拦截规则(切点)作为参数。 (3)其中@After、@Before、@Around参数的拦截规则为切点(PointCut),为了使切点复用,可使用@PointCut专门定义拦截规则,然后在@After、@Before、@Around的参数中调用。 (4)其中符合条件的每一个被拦截处为连接点(JoinPoint)。 其中: @Before是在所拦截方法执行之前执行一段逻辑。 @After 是在所拦截方法执行之后执行一段逻辑。 @Around是可以同时在所拦截方法的前后执行一段逻辑。

详细配置方式 见:https://git.oschina.net/os_val/SpringBootDemo.git 其中的Spring AOP包下。

Bean的Scope Scope描述的是Spring容器如何新建bean的实例,Scope有以下几种,通过@Scope注解实现。 (1)Singleton(单例):一个Spring容器中只有一个bean的实例,此为Spring的默认配置,全容器共享一个实例。 (2)Prototype(原型):每次调用新建一个bean实例。 (3)Reqeuest:web项目中,给每一个http request新建一个bean实例。 (4)Session:web项目中,给每一个http session新建一个bean实例。 (5)GlobalSession:这个只在portal应用中有,给每一个global http session新建一个bean实例。 详细见:https://git.oschina.net/os_val/SpringBootDemo.git 其中的Spring Bean包下。

Spring EL 和 资源调用

SpringEL 表达式相当于JSTL。Spring调用各种资源可以使用Spring 表达式语音实现资源的注入。 注解@Value的参数中可以使用表达式语言,可注入包括普通字符、操作系统属性、表达式运算结果、其他bean属性、文件内容、网址内容、属性文件等。

package com.spring.EL;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * Created by zsq on 16/12/18.
 */
@Service
public class DemoService {
    /**
     * 注入普通字符
     */
    @Value(value = "其他类的属性")
    private String another;

    public String getAnother() {
        return another;
    }

    public void setAnother(String another) {
        this.another = another;
    }
}

package com.spring.EL;

import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;

import java.io.IOException;

/**
 * Created by zsq on 16/12/18.
 * 其中test.properties 配置文件和test.txt 文本文件是放在 idea中的resources 目录下
 */
@Configuration
@ComponentScan(value = "com.spring.EL")
@PropertySource(value = "test.properties")
public class ELConfig {

    /**
     * 注入普通字符
     */
    @Value("this is java")
    private String normal;

    /**
     * 注入操作系统属性
     */
    @Value("#{systemProperties['os.name']}")
    private String osName;

    /**
     * 注入表达式结果
     */
    @Value("#{ T(java.lang.Math).random()*100.0}")
    private double randomNumber;

    /**
     * 注入其他bean属性
     */
    @Value("#{demoService.another}")
    private String fromAnother;

    /**
     * 注入文件资源
     */
    @Value("test.txt")
    private Resource textFile;

    /**
     * 注入网址资源
     */
    @Value("http://www.baidu.com")
    private Resource testURL;

    /**
     * 注入配置文件 此处使用${}
     */
    @Value("${book.name}")
    private String bookName;

    @Autowired
    private Environment environment;

    /**
     * 注入配置文件则需要@PropertySource 指定文件地址
     * 若使用@Value 注入还需要配置一个PropertySourcesPlaceholderConfigurer的bean
     * 注入的Properties 可以从Environment中获得
     * @return
     */
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfig() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    public void outputResource() throws IOException {
        System.out.println(normal);
        System.out.println(osName);
        System.out.println(randomNumber);
        System.out.println(fromAnother);
        System.out.println(IOUtils.toString(textFile.getInputStream()));
        System.out.println(IOUtils.toString(testURL.getInputStream()));
        System.out.println(bookName);
        System.out.println(environment.getProperty("book.author"));
    }
}

public class ELMain {

    public static void main(String[] args) throws IOException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ELConfig.class);
        ELConfig elConfig = context.getBean(ELConfig.class);
        elConfig.outputResource();
        context.close();
    }
}

Profile profile为在不同环境下使用不同的配置提供了支持(开发和生成环境)。使用@Profile注解。

package com.spring.Profile;

/**
 * Created by zsq on 16/12/18.
 */
public class DemoBean {

    private String content;

    public DemoBean(String content) {
        this.content = content;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}

package com.spring.Profile;

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

/**
 * Created by zsq on 16/12/18.
 */
@Configuration
public class ProfileConfig {

    /**
     * 实例化 devDemoBean
     * @return
     */
    @Bean
    @Profile("dev")
    public DemoBean devDemoBean() {
        return new DemoBean("from development profile");
    }

    /**
     * 实例化 prodDemoBean
     * @return
     */
    @Bean
    @Profile("prod")
    public DemoBean prodDemoBean() {
        return new DemoBean("from production profile");
    }
}


package com.spring.Profile;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.io.IOException;

/**
 * Created by zsq on 16/12/18.
 */
public class ProfileDemoMain {

    public static void main(String[] args) throws IOException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
        context.getEnvironment().setActiveProfiles("prod");
        context.register(ProfileConfig.class);
        context.refresh();

        DemoBean demoBean = context.getBean(DemoBean.class);
        System.out.println(demoBean.getContent()); //from production profile

        context.close();
    }
}

事件(Application Event) Spring的事件(Application Event)为bean与bean之间的消息通信提供了支持。当一个bean处理完任务,希望另一个bean知道并作出相应的处理。这时要让另一个bean监听当前bean所发送的事件。 Spring的事件流程: (1)自定义事件,集成(继承)Application Event 类。 (2)定义事件监听器,实现ApplicationListener 接口 并实现onApplicationEvent(Event event) 方法。 (3)使用容器发布事件。

package com.spring.Event;

import org.springframework.context.ApplicationEvent;

/**
 * Created by zsq on 16/12/18.
 * 自定义事件
 */
public class DemoEvent extends ApplicationEvent{
    private String msg;

    public DemoEvent(Object source, String msg) {
        super(source);
        this.msg = msg;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

package com.spring.Event;

import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

/**
 * Created by zsq on 16/12/18.
 * 事件监听
 * 实现ApplicationListener 并指定监听的类型DemoEvent
 */
@Component
public class DemoListener implements ApplicationListener<DemoEvent>{

    /**
     * 对消息进行接收处理
     * @param demoEvent
     */
    @Override
    public void onApplicationEvent(DemoEvent demoEvent) {
        String content = demoEvent.getMsg();
        System.out.println("demoListener接收到demoPublisher的信息:"+content);
    }
}

package com.spring.Event;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

/**
 * Created by zsq on 16/12/18.
 * 消息发布类
 */
@Component
public class DemoPublisher {

    @Autowired
    private ApplicationContext applicationContext;

    public void publish(String msg) {
        applicationContext.publishEvent(new DemoEvent(this, msg));
    }
}

package com.spring.Event;

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

/**
 * Created by zsq on 16/12/18.
 */
@Configuration
@ComponentScan(value = "com.spring.Event")
public class EventConfig {
}

package com.spring.Event;

import com.spring.Profile.DemoBean;
import com.spring.Profile.ProfileConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.io.IOException;

/**
 * Created by zsq on 16/12/18.
 */
public class EventDemoMain {

    public static void main(String[] args) throws IOException {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class);
        DemoPublisher demoPublisher = context.getBean(DemoPublisher.class);
        demoPublisher.publish("this is application event");
        //demoListener接收到demoPublisher的信息:this is application event
        context.close();
    }
}
1
https://gitee.com/os_val/SpringBootDemo.git
git@gitee.com:os_val/SpringBootDemo.git
os_val
SpringBootDemo
SpringBootDemo
master

搜索帮助