SpringFramework解决了什么问题?

Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品。无需开发重量级的EnterpriseJavaBean(EJB)Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象(Plain Old Java Object,POJO)实现了EJB的功能。

  • 使用SpringIOC容器,将对象之间的依赖关系交给Spring,降低组件之间的耦合性,让我们更专注于应用逻辑
  • 可以提供众多服务,事务管理,WS等。
  • AOP的面向切面编程。
  • 对主流的框架提供了很好的集成支持,如Hibernate,Struts2,JPA
  • Spring DI机制降低了业务对象替换的复杂性。
  • Spring属于低侵入,代码污染极低。
  • Spring的高度可开放性,并不强制依赖于Spring,开发者可以自由选择Spring部分或全部

SpringFramework没有解决了什么问题?

虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。一开始,SpringXML配置,而且是很多XML配置。Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。Spring 3.0引入了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML。所有这些配置都代表了开发时的损耗。因为在思考Spring特性配置和解决业务问题之间需要进行思维切换,所以编写配置挤占了编写应用程序逻辑的时间。和所有框架一样,Spring实用,但与此同时它要求的回报也不少。除此之外,项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。

SpringBoot的缘由

为什么有了SpringFramework还会诞生SpringBoot?因为虽然Spring的组件代码是轻量级的,但它的配置却是重量级的;所以SpringBoot的设计策略是通过开箱即用约定大于配置来解决配置重的问题的。

SpringBoot的特点

为基于Spring的开发提供更快的入门体验开箱即用,没有代码生成,也无需XML配置。同时也可以修改默认值来满足特定的需求提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标,健康检测、外部配置等SpringBoot不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式

SpringBoot的核心功能

起步依赖

起步依赖本质上是一个Maven项目对象模型(Project Object Model,POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能。简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能。

自动配置

Spring Boot的自动配置是一个运行时(更准确地说,是应用程序启动时)的过程,考虑了众多因素,才决定Spring配置应该用哪个,不该用哪个。该过程是Spring自动完成的。

Spring Boot 常用注解

@SpringBootApplication:定义在main方法入口类处,用于启动SpringBoot应用项目

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {

	/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 * @return the classes to exclude
	 */
	Class<?>[] exclude() default {};

}

@EnableAutoConfiguration:让SpringBoot根据类路径中的jar包依赖当前项目进行自动配置

src/main/resourcesMETA-INF/spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration

若有多个自动配置,用“,”隔开

@ImportResource:加载xml配置,一般是放在启动main类上

@ImportResource("classpath*:/spring/*.xml")  单个

@ImportResource({"classpath*:/spring/1.xml","classpath*:/spring/2.xml"})   多个

@Valueapplication.properties定义属性,直接使用@Value注入即可

public class A{
	 @Value("${push.start:0}")   // 如果缺失,默认值为0
     private Long  id;
}

@ConfigurationProperties(prefix="person") :可以新建一个properties文件,ConfigurationProperties的属性prefix指定properties的配置的前缀,通过location指定properties文件的位置

@ConfigurationProperties(prefix="person")
public class PersonProperties {
	
	private String name ;
	private int age;
}

@EnableConfigurationProperties :用@EnableConfigurationProperties注解使 @ConfigurationProperties生效,并从IOC容器中获取bean

@RestController :组合@Controller@ResponseBody

@RequestMapping("/"):用来映射web请求(访问路径和参数)、处理类和方法,可以注解在类或方法上。注解在方法上的路径会继承注解在类上的路径。produces属性: 定制返回的response的媒体类型和字符集,或需返回值是json对象

@RequestMapping(value="/api/test",produces="application/json;charset=UTF-8",method = RequestMethod.POST)

@RequestParam 获取request请求的参数值

public List<CopperVO> getOpList(HttpServletRequest request,
                                    @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
                                    @RequestParam(value = "pageSize", required = false) Integer pageSize) {
 
}

@ResponseBody 支持将返回值放在response体内,而不是返回一个页面。比如Ajax接口,可以用此注解返回数据而不是页面。此注解可以放置在返回值前或方法前。

@Bean @Bean(name="bean的名字",initMethod="初始化时调用方法名字",destroyMethod="close")定义在方法上,在容器内初始化一个bean实例类。

@Bean(destroyMethod="close")
@ConditionalOnMissingBean
public PersonService registryService() {
		return new PersonService();
	}

@Service 用于标注业务层组件

@Controller用于标注控制层组件

@Repository用于标注数据访问组件,即DAO组件

@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。

@PostConstruct spring容器初始化时,要执行该方法

@PostConstruct  
public void init() {   
}

@PathVariable 用来获得请求url中的动态参数

@Controller  
public class TestController {  

     @RequestMapping(value="/user/{userId}/roles/{roleId}",method = RequestMethod.GET)  
     public String getLogin(@PathVariable("userId") String userId,  
         @PathVariable("roleId") String roleId){
           
         System.out.println("User Id : " + userId);  
         System.out.println("Role Id : " + roleId);  
         return "hello";  
     
     }  
}

@ComponentScan 注解会告知Spring扫描指定的包来初始化Spring

@ComponentScan(basePackages = "com.bbs.xx")

@EnableZuulProxy 路由网关的主要目的是为了让所有的微服务对外只有一个接口,我们只需访问一个网关地址,即可由网关将所有的请求代理到不同的服务中。Spring Cloud是通过Zuul来实现的,支持自动路由映射到在Eureka Server上注册的服务。Spring Cloud提供了注解@EnableZuulProxy来启用路由代理。

@Autowired 在默认情况下使用 @Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个。当找不到一个匹配的 Bean 时,Spring 容器将抛出 BeanCreationException 异常,并指出必须至少拥有一个匹配的 Bean。当不能确定 Spring 容器中一定拥有某个类的 Bean 时,可以在需要自动注入该类 Bean 的地方可以使用 @Autowired(required = false),这等于告诉 Spring在找不到匹配 Bean 时也不报错

@Configuration 表示这是一个配置信息类 , @Configuration("name") 可以给这个配置类也起一个名称

@Configuration("name")
@ComponentScan("spring4")//类似于xml中的<context:component-scan base-package="spring4"/>
public class Config {

    @Autowired//自动注入,如果容器中有多个符合的bean时,需要进一步明确
    @Qualifier("compent")//进一步指明注入bean名称为compent的bean
    private Compent compent;

    @Bean//类似于xml中的<bean id="newbean" class="spring4.Compent"/>
    public Compent newbean(){
        return new Compent();
    }   
}l

@Import(Config1.class) 导入Config1配置类里实例化的bean

@Configuration
public class CDConfig {

    @Bean   // 将SgtPeppers注册为 SpringContext中的bean
    public CompactDisc compactDisc() {
        return new CompactDisc();  // CompactDisc类型的
    }
}

@Configuration
@Import(CDConfig.class)  //导入CDConfig的配置
public class CDPlayerConfig {

    @Bean(name = "cDPlayer")
    public CDPlayer cdPlayer(CompactDisc compactDisc) {  
         // 这里会注入CompactDisc类型的bean
         // 这里注入的这个bean是CDConfig.class中的CompactDisc类型的那个bean
        return new CDPlayer(compactDisc);
    }
}

@Order @Order(1),值越小优先级超高,越先运行

@ConditionalOnExpression 开关为true的时候才实例化bean

@Configuration
@ConditionalOnExpression("${enabled:false}")
public class BigpipeConfiguration {
    @Bean
    public OrderMessageMonitor orderMessageMonitor(ConfigContext configContext) {
        return new OrderMessageMonitor(configContext);
    }
}