首先理解什么是Bean。凡是有方法或属性的类都需要实例化,这样才能具象化去使用这些方法和属性,把Bean理解为类的代理或代言人(实际上确实是通过反射、代理来实现的),这样它就能代表类拥有该拥有的东西了,就可以去使用了。什么是注解。注解就是@XX,如果你使用@XX,Spring就会过来看看,帮你注册一个Bean或者从Spring IOC中拿Bean。
  大体上注解分成两种。一是注册Bean,就是将你的类或者方法转化成一个Bean,注册到Spring IOC中,如@Component , @Repository , @ Controller , @Service;另一种,就是从Spring IOC中获取一个Bean,如@Autowired , @Resource。

前期准备

  打算使用代码来讲解注解,这就需要先创建例程:
  有TigerMonkeyICarBenzCarBMWCar

public class Tiger {
    private String tigerName="TigerKing";
    public String toString(){
        return "TigerName:"+tigerName;
    }
}
public class Monkey {
    private String monkeyName = "MonkeyKing";
    public String toString(){
        return "MonkeyName:" + monkeyName;
    }
}
public interface ICar {
    public String getCarName();
}
public class BenzCar implements ICar{
    public String getCarName(){
        return "Benz car";
    }
}
public class BMWCar implements ICar{
    public String getCarName(){
        return "BMW car";
    }
}

常用的注解

1、@Autowired

  顾名思义,自动装配。按照类型匹配,在容器中查找匹配的Bean。当有且仅有一个匹配的Bean时,Spring将其注入@Autowired标注的变量中。
  先注册一些Bean。包括tigermonkey

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    ">
    <context:component-scan base-package="com.spring" />
    <bean id="tiger" class="com.spring.model.Tiger" />
    <bean id="monkey" class="com.spring.model.Monkey" />
</beans>

  如果不是Spring,那我们使用的时候就是 Tiger tiger = new Tiger( )。@Autowired十分方便我们将获取实例。

public class Zoo {
    @Autowired
    private Tiger tiger;
    @Autowired
    private Monkey monkey;    
}

  @Autowired会自动匹配类型,并自动注入进来。如果没有事先注入的Bean,而使用@Autowired就会在编译时候报错,有没有优化方法,有。

@Autowired(required=false)
    private Tiger tiger;

  这样在找不到Bean时也不会报错,只不过tiger属性为null。

2、@Qualifier

  如果容器中有一个以上匹配的Bean,则可以通过@Qualifier注解限定Bean的名称。
  向Spring IOC添加新的注解,宝马车和奔驰车,这两个车都是继承ICar。

<bean id="bmwCar" class="com.spring.service.impl.BMWCar" />
    <bean id="benz" class="com.spring.service.impl.BenzCar" />

  如果你正好要出行,这个时候需要一个车,好,获取一个呗:

@Autowired
    private ICar car;

  这个时候Spring这个管家就生气了,什么鬼,到底什么车,奔驰还是宝马。如果说ICar只有一个继承实现类,那好说,直接使用一个就好了。但是多个实现就有问题了,不知道使用那个实现类。这个时候使用@Qualifier 来指明使用哪个Bean。所以决定以后出行都用宝马。此处会注入名为”bmwCar”的Bean。

@Autowired
    @Qualifier("bmwCar")
    private ICar car;
3、@Resource

  这个@Resource注解与@Autowired注解作用非常相似。

@Resource(name="tiger")
    private Tiger tiger;

    @Resource(type=Monkey.class)
    private Monkey monkey;

  这是详细一些的用法,说一下@Resource的装配顺序:
1. @Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配
2. 指定了name或者type则根据指定的类型去匹配bean
3. 指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错

  然后,区分一下@Autowired和@Resource两个注解的区别:
1. @Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配
2. @Autowired是Spring的注解,@Resource是J2EE的注解,这个看一下导入注解的时候这两个注解的包名就一清二楚了

4、@Service

  通过上面的例子会发现,好累,每次都要写个xml去存放Spring的Bean,一旦项目变大,那这个xml会变得非常庞大和复杂,难以维护。有没有方法解决,有的。@Service。@Service的作用就是将注解的地方生成一个Bean注册到Spring IOC中管理。

@Service
public class Monkey {
    private String monkeyName = "MonkeyKing";
    public String toString(){
        return "MonkeyName:" + monkeyName;
    }
}

  上述就是将Monkey这个类生成一个Monkey Bean注册到Spring IOC中。@Service注解,其实做了两件事情:
1. 声明Monkey.java是一个bean,这点很重要,因为Monkey.java是一个bean,其他的类才可以使用@Autowired将Monkey作为一个成员变量自动注入。
2. Monkey.java在bean中的id是”monkey”,即类名且首字母小写。
  如果有一些特殊的癖好,我不要小猴,我要大猴,怎么办,那就注册的时候指定名称@Service(“Monkey”)。

5、@Scope

  Spring 管家有一个有癖好的人。Spring默认产生的bean是单例的。默认是”singleton”即单例,”prototype”表示原型即每次都会new一个新的出来。

@Service("monkey")
@Scope("prototype")
public class Monkey {
    private String monkeyName = "MonkeyKing";
    public String toString(){
        return "MonkeyName:" + monkeyName;
    }
}
6、@Controller

  @Controller对应表现层的Bean,也就是Action。这个也是与@Service相似,向Spring注册一个Bean,@Service是对应的是业务层Bean。

7、@ Repository

  @Repository对应数据访问层Bean。

@Repository("userDao")
public class UserDaoImpl implements BaseDao {
………
}

  @Repository(“userDao”)注解是告诉Spring,让Spring创建一个名字叫”userDao”的UserDaoImpl实例。
  当需要使用Spring创建的名字叫”userDao”的UserDaoImpl实例时,就可以使用@Autowired(“userDao”)注解告诉Spring,Spring把创建好的userDao注入即可。

@Autowired("userDao")
private BaseDao userDao;

  @Repository,@Service和@Controlle这三个没什么功能上的差别,差别只是在语义上,@Repository/@Service/@Controller分别代表了特定语义的类, @Repository:用于标注数据访问组件,即DAO组件我们注解这个类,更多的是对它有个数据库操作的管理,比如你继承了spring自己的hibernateDAo这样的东西,那怎么给你注入一些数据库操作的元素了,就靠它了,所以这个不是随便注释的。

8、@ Bean 和 @Configuration

  @Bean明确地指示了一种方法,什么方法呢?!产生一个bean的方法,并且交给Spring容器管理;从这我们就明白了为啥@Bean是放在方法的注释上了,因为它很明确地告诉被注释的方法,你给我产生一个Bean,然后交给Spring容器,剩下的你就别管了。@Bean常常和@Configuration配合使用。
  @Configuration可理解为用spring的时候xml里面的< beans >标签
  @Bean可理解为用spring的时候xml里面的< bean >标签

@Configuration  
public class ExampleConfiguration {  

    @Value("com.mysql.jdbc.Driver")  
    private String driverClassName;  

    @Value("jdbc://xxxx.xx.xxx/xx")  
    private String driverUrl;  

    @Value("${root}")  
    private String driverUsername;  

    @Value("123456")  
    private String driverPassword;  

    @Bean(name = "dataSource")  
    public DataSource dataSource() {  
        BasicDataSource dataSource = new BasicDataSource();  
        dataSource.setDriverClassName(driverClassName);  
        dataSource.setUrl(driverUrl);  
        dataSource.setUsername(driverUsername);  
        dataSource.setPassword(driverPassword);  
        return dataSource;  
    }  

    @Bean  
    public PlatformTransactionManager transactionManager() {  
        return new DataSourceTransactionManager(dataSource());  
    }   
}

  这样就可以在项目中使用@Autowired去获取实例。

@Autowired
private DataSource dataSource;
9、@ Value

  @ Value是用于简化读取properties文件中的配置值,spring支持@value注解的方式来获取,这种方式大大简化了项目配置,提高业务中的灵活性。

两种使用方法
@Value("#{configProperties['key']}")
@Value("${key}")   <- 推荐这种
9.1 第一种配置

  在配置文件中写上

<!-- @Value -->
<bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">  
    <property name="locations">  
        <list>  
           <value>classpath*:hahaha.properties</value>  
         </list>  
    </property>  
</bean>

  并在src下添加配置文件hahaha.properties,内容如下:

my.name=hahaha
my.age=27
9.2 第二种配置

  在配置文件中写上

<!-- @Value -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="ignoreUnresolvablePlaceholders" value="true"/>
        <property name="locations">
            <list>
                <value>classpath:hahaha.properties</value>
            </list>
        </property>
    </bean>

  并在src下添加配置文件hahaha.properties

10、@RequestMapping

  用来处理请求地址映射的注解。

@Controller
//设置想要跳转的父路径
@RequestMapping(value = "/Controllers")
public class StatisticUserCtrl {
            // 设置方法下的子路经
            @RequestMapping(value = "/method")
            public String helloworld() {
                return "helloWorld";
            }
}

  其对应的 action就是“/Controllers/method”,通过 “http://localhost:8080/Controllers/method ”就可以访问该方法。

11、@ResponseBody

  该方法的返回的结果直接写入 HTTP 响应正文(ResponseBody)中,返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用。方法无法返回jsp页面,配置的视图解析器InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。

12、@RequestBody

  @RequestBody 注解则是将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。
  用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上
  再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上。

@RequestMapping(value = "/main/addUserInfo")
    public ResultBean addUserInfo(@RequestBody UserInfo userInfo) {
    }

  GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。
  POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上。

13、@RequestParam

  指定输入的参数。

@RequestMapping(value = "/main/addName")
    public ResultBean addName(@RequestParam(value = "name", defaultValue = "haha") String userInfo) {
    }
14、@RestController

  该注解其实就是@ResponseBody + @Controller, @Controller配合视图解析器InternalResourceViewResolver才行。如果需要返回JSON,XML或自定义mediaType内容到页面,则需要RestController。

15、@Scheduled

  这个是定时器注解。可以定时或者定间隔的启动某个任务。它带有三种定时运行方式,fixedDelay、fixedRate和cron表达式。

fixedDelay <- 上一次任务结束后,完整的延迟时间后再执行。
fixedRate <- 按照整点时间划分,如果上一次任务没执行完,就等他执行完后立马执行,任务持续累加、阻塞。
cron  <- 定制化定时时间,上一次任务结束后的最近整点时间开始执行。

  一张图看懂运行方式

下列不属于Spring Boot的缓存注解的是_Spring


  initialDelay这个参数用来延迟启动之用。