springboot 建readme_README.md · 花开自相依丶/SpringBootDemo - Gitee.com

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

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

Spring框架结构图

![Spring框架图](http://git.oschina.net/uploads/images/2016/1222/192544_f2ea29c4_432131.png "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{

/**

* 对消息进行接收处理

* @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();

}

}

```

一键复制

编辑

Web IDE

原始数据

按行查看

历史

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值