Spring Boot

Spring

Spring按照模块进行组织

Spring生态

提供大量Spring的项目 更深入地降低我们的开发难度 提高开发效率

  • Spring Boot 使用默认开发配置来实现快速开发

构建工具

主流的项目构建工具, Ant、Maven、Gradle

Apache Maven是软件项目管理工具, 基于项目对象模型(POM)管理项目的依赖、编译、文档信息

配置M2_HOME和Path(%M2_HOME%\bin)

可以将本地jar打到本地的Maven仓库

Spring四大原则

  • 使用POJO -> 低侵入
  • 依赖注入 面向接口 -> 松散耦合
  • 切面编程
  • 减少样板代码

注解

(元数据 数据的数据)没有实际功能 需要解释为执行某些有意义的动作

  1. 创建bean @Component @Repository @Controller @Service
  2. 注入bean @Autowired @Inject @Resource

AOP

  • AOP弥补OOP(面向对象编程)的不足
  • Spring支持AspectJ的注解式切面编程
  1. @AspectJ声明一个切面
  2. @After @Before @Around定义advice 拦截规则(切点)作为参数
  3. 每一个被拦截处称为连接点(JoinPoint)

注解式拦截能够很好地控制拦截的粒度 更丰富的信息

aop支持及其AspectJ依赖

<!-- spring aop支持-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.1.6.RELEASE</version>
</dependency>
<!-- aspectj支持-->
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.5</version>
</dependency>

拦截规则的注解 注解本身没有功能 是元数据(解释数据的数据)

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
    String name();
}

切面编写 1、注解式拦截 2、方法规则式拦截

package spring.boot.ch1.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author BobWaters
 * @create 2018-06-05 下午11:44
 */

@Aspect
@Component
public class LogAspect {

    @Pointcut("@annotation(spring.boot.ch1.aop.Action)")
    public void annotationPointCut() {
    }

    @After("annotationPointCut()")
    public void after(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Action action = method.getAnnotation(Action.class);
        System.out.println("注解式拦截 " + action.name());
    }

    @Before("execution(* spring.boot.ch1.aop.DemoMethodService.*(..))")
    public void before(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        System.out.println("方法规则式拦截 " + method.getName());
    }

}

另外, 配置类上需要增加@EnableAspectJAutoProxy注解, 开启Spring对AspectJ的支持。

@Value注解

 

  1. 大部分情形下使用#{}, 只有读取配置文件中的属性时使用${}(//1处)
  2. 配合使用@PropertySource注解时需要声明PropertySourcesPlaceholderConfigurer这个Bean, 且必须是static(//2处)
  3. 另外配置文件中的属性还有一种读取方式(//3处)
  4. 最后配置文件没有加@Configuration(//4处)照常生效
package spring.boot.ch2.spel;

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.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;


/**
 * @author BobWaters
 * @create 2018-06-06 上午9:03
 */

//4
@ComponentScan("spring.boot.ch2.spel")
@PropertySource("classpath:spring/boot/ch2/spel/test.properties")
public class SpelConfig {
    @Value("Hello world")
    String normal;

    @Value("#{systemProperties['os.name']}")
    String osName;

    @Value("#{T(java.lang.Math).random() * 100}")
    String randomNum; //double也可以

    @Value("#{demoService.another}")
    String fromAnother;

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

    @Value("classpath:spring/boot/ch2/spel/test.txt") //注入文件资源
    Resource txt;

    @Value("${program.author}")//1
    String authorName;

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigurer() { //2
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Autowired
    Environment environment; //自动创建了enviroment //3

    //@Value("${environment.getProperty('age')}")
    //String age; //3


    public void outputResource() throws Exception {
        System.out.println(normal);
        System.out.println(osName);
        System.out.println(randomNum);
        System.out.println(fromAnother);
        System.out.println(IOUtils.toString(url.getInputStream()));
        System.out.println(IOUtils.toString(txt.getInputStream()));
        System.out.println(authorName);
        System.out.println(environment.getProperty("age"));//3
    }
}

Bean的自定义操作

引入JSR250-api的jar包

<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.2</version>
</dependency>

如果采用JavaConfig的方式 在@Bean注解中使用initMethod和destroyMethod

如果使用完全注解的方式 那么在对应的方法是加上@PostConstructor @PreDestroy

Profile配置

在对应的@Bean注解上加上@Profile("product")或@Profile("dev")注解

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("product"); //激活对应环境
context.register(ProfileConfig.class);//加载配置类
context.refresh();

可以配置profile的地方

 

  • servelt2.5 web.xml
  • servlet3.0 java文件中设置
  • jvm 参数设置环境变量

 

事件监听

  • Event: 继承ApplicationEvent 内含message信息
  • Publisher: 内部@Autowired注入一个ApplicationContext 使用ApplicationContext的publishEvent()事件
  • Listener: 实现ApplicationListener<T> T为事件类型 实现onApplicationEvent(T t)方法

Spring Aware

 

实现BeanNameAware可以获取bean的名称 实现ResourceLoaderAware可以获得ResourceLoader

实现ApplicationContext可以获取达到以上所有效果 这些都会与Spring耦合

ResourceLoader的getResource方法可以根据路径参数读取获得Resource对象

使用IOUtils.toString()将resource的getInputStream()输出

多线程与异步

使用基于线程池的任务执行器 ThreadPoolTaskExecutor

 

  • 配置类上加@EnableAsync注解
  • 配置类实现AsyncConfigurer(实现两个方法)
  • Service类中的异步方法上加@Async注解
package spring.boot.ch3.taskexecutor;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

/**
 * @author BobWaters
 * @create 2018-06-10 上午12:56
 */

@ComponentScan("spring.boot.ch3.taskexecutor")
@Configuration
@EnableAsync
public class TaskExecutorConfig implements AsyncConfigurer {
    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.initialize();
        return executor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }
}

定时任务

 

  • 配置类使用@EnableScheduling开启
  • 定时执行的方法上使用@Scheduled注解修饰 参数可以为cron fixRate等

@Conditional

 

  • 创建若干的条件继承Condition接口
  • @Conditional注解使用在@Bean标注的方法上,传入参数是实现Condition接口的类,控制bean的创建
  • 另外,容器context可以获得environment继而可以获得os.name等

组合注解

package spring.boot.ch3.annotation;

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

import java.lang.annotation.*;

/**
 * @author BobWaters
 * @create 2018-06-10 上午10:53
 */

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ComponentScan
@Configuration
public @interface WiselyConfiguration {
    String[] value() default {}; //覆盖value参数
}

@Enable*

每个注解定义上上都有@Import注解,作用是

 

  1. 直接导入配置类 例如@EnableScheduling
  2. 依据条件选择配置类 例如@EnableAsync
  3. 动态注册Bean 例如@EnableAspectJAutoProxy

 

集成测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TConfig.class})
@ActiveProfiles("prod")

 

  • SpringJUnit4ClassRunner提供Junit环境下Spring TestContext Framework的功能
  • ContextConfiguration加载ApplicationContext classes指定配置类
  • ActiveProfiles声明活动的profile

注意:

 

  • junit至少使用4.12
  • spring-test版本不合适会报错

在配置文件里面没有配置

spring.profiles.active=test
***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method sqlSessionFactory in com.sankuai.appflow.eventanalyze.config.OceanDbConfiguration required a bean of type 'javax.sql.DataSource' that could not be found.

The injection point has the following annotations:
	- @org.springframework.beans.factory.annotation.Qualifier(value=oceanDataSource)

The following candidates were found but could not be injected:
	- Bean method 'dataSource' in 'JndiDataSourceAutoConfiguration' not loaded because @ConditionalOnProperty (spring.datasource.jndi-name) did not find property 'jndi-name'
	- Bean method 'dataSource' in 'XADataSourceAutoConfiguration' not loaded because @ConditionalOnClass did not find required class 'javax.transaction.TransactionManager'


Action:

Consider revisiting the entries above or defining a bean of type 'javax.sql.DataSource' in your configuration.

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值