springboot白皮书

1.自定义注解本身是没有功能的,让注解生效是你如何使用注解,比如拦截指定自定义注解

1.1IDEA创建自定义注解:new    -   java class    -    annotation

2.el表达式有默认值 

@Value("${property:default value}")

比如 @Value("${mongodb.url:127.0.0.1}")

3.@PropertySource可以指定文件地址 

4.@Profile 可与spring.profiles.active一起使用 

比如设置环境变量-Dspring.profiles.active=dev或者application.yml种指定spring.profiles.active:dev  会执行被@Profile("dev")注解的方法

(不一定非得spring.profiles.active ,是一个可以从配置文件中读到的属性就好,可以给他一个默认值)

5.spring的监听事件:观察者模式

5.1.自定义事件类继承ApplicationEvent

5.2.监听器实现ApplicationListener

5.3.监听器重写onApplicationEvent方法,监听1.中自定义事件类

5.4.发布publishEvent自定义事件类

5.6可以用@EventListener注解,更方便

Spring事件监听器之@EventListener原理分析_java_脚本之家

Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式;为的就是业务系统逻辑的解耦,提高可扩展性以及可维护性。事件发布者并不需要考虑谁去监听,监听具体的实现内容是什么,发布者的工作只是为了发布事件而已。

在spring中我们可以通过实现ApplicationListener接口或者@EventListener接口来实现事件驱动编程

比如我们做一个电商系统,用户下单支付成功后,我们一般要发短信或者邮箱给用户提示什么的,这时候就可以把这个通知业务做成一个单独事件监听,等待通知就可以了;把它解耦处理。

public class OrderEvent extends ApplicationEvent {
    public OrderEvent(Object source) {
        super(source);
    }
}
@Component
public class OrderEventListener  {
    @EventListener
    public void listener(OrderEvent event) {
        System.out.println("i do OrderEventListener" );
    }
}
@Controller
@RequestMapping("person")
public class PersonController implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    @ResponseBody
    @GetMapping("publishOrderEvent")
    public String publishOrderEvent() {
        applicationContext.publishEvent(new OrderEvent("我发布了事件!!!"));
        System.out.println(" publishOrderEvent ");
        return "发送事件了!";
    }
}

 5.7监听是同步的

如果要改为异步,需使用@Async注解

5.8事务提交之后再执行监听方法

@EventListener
改为
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT,fallbackExecution = true)

6.@Async注解

注解在方法上表名该方法是一个异步方法

注解在类上表名该类所有的方法都是异步方法

7.spring提供了很多@Enable*注解

如@EnableAsync开启异步,@EnableSchedule开启定时,

@EnableConfigurationProperties开启对@ConfigurationProperties的支持(当然  如果@ConfigurationProperties结合@Component注解一起使用,也可以不用@EnableConfigurationProperties注解)

8.@EnableSchedule

使用@Schedule注解,定时执行被@Schedule注解的方法,如@Schedule(cron="")或者@Schedule(多久执行一次)

9.条件注解@Conditional

9.1@Conditional根据满足某一个指定条件创建一个特定的bean

@Conditional(A.class)

其中A实现了Condition接口并且重写了matches方法,其中matches方法是boolean型的,如果返回true,则创建被@Condition注解的bean,如果false,则不创建该bean

9.2@ConditionalOnMissingBean与@ConditionalOnBean含义正好相反

9.3@ConditionalOnBean和@ConditionalOnClass的区别:class是存在这个类就返回true,bean是必须是一个被spring管理的bean,比如他必须有@Component注解

10.@ConfigurationProperties(prefix="xx")

同样是从配置文件中取值,我理解@Value和@ConfigurationProperties的区别

10.1@Value是一个值一个值取,@ConfigurationProperties是根据前缀一堆一堆取值

10.2@ConfigurationProperties用在类上,对应属性有get,set方法

10.3@Value只能从application.yml/properties文件中取值,@ConfigurationProperties可以结合@PropertySource从其他配置文件中取值,比如@PropertySource(value = {"classpath:user.properties"})

11.老生常谈的@Controller和@RestController

@Controller根据配置的前缀后缀返回页面,@Controller返回的字符串只是页面的名称,比如返回index,那么就会返回一个index.jsp或者index.html的页面

@RestController组合注解,@ResponseBody+@Controller 返回json 而不是页面

如果你想给前端返回一个字符串,就用@RestController

12.从没有用过@PathVariable

从路径取值接受参数

@RequestMaping(value="/test/{str}")

public String test(@PathVariable String str){}

13.一个方法可以有多个接口名

@RequastMappint(value={"/test1","/test2"})

public String test(){}

注意:虽然他们都注解了test这个方法,如果你拦截器里只拦截/test1接口,当他访问/test2接口时是不走你得拦截器的

14.全局异常处理

@ControllerAdvice+@ExceptionHandler

就近原则>@ControllerAdvice

踩过的一个坑:我访问被@RequestMapping注解的方法抛异常后,没有进如下断点

@ControllerAdvice(basePackageClasses = BREConfig.class)
@Slf4j
@Order(1)
public class AdviceTest {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String testException(Exception e){
        log.info("测试advice");
        return "";
    }
}

原因,在BREConfig类中,已经存在被@ExceptionHandler注解的方法,优先走同一个类中的拦截

之后,我把同一个类的@ExceptionHandler注解去掉,断点果然进入到@ControllerAdvice类中

@ControllerAdvice只在springMvc中生效,然后springboot是基于springmvc的,所以生效,但是如果在sofaboot中,如果还访问被@RequestMapping注解的方法,可以生效,如果是通过rest,bolt访问,就不生效了,我理解是

15.starter,被别人引用的jar包

关键点:spring.factories

如何配置:

1.文件位置:resource下建立META-INF文件夹

2.内容:\换行符,多个时用半角逗号分割

用处:扫描@Configuration

如果在引用者的启动类中配置扫描路径中包括该@Configuration的类,也可以不配置spring.factories,但是作为公共starter,不应该这样耦合,为了解耦

如何扫描:核心注解@SpringBootApplication中有关于SpringFactoriesLoader的配置,会扫描所有spring.factories

16.application.yml优先级

jar包外部>jar包内部,application-{profile}.yml>application.yml,

互补配置,并且当优先级高的配置会覆盖优先级低的配置

使用apollo的情况下,apollo的优先级更大

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值