[TOC]

一 @Autowired

  • 通过 @Autowired 的使用来消除 set ,get方法

    注:区别于Lombok,lombok是生成set和get方法,你能直接使用 ;

@Autowired 是用来注值的,spring注值本质上是用了set方法来找到对象并初始化的,在这个注解没出来前,需要写get,set方法

  • 通过(1),可以看到,@Autowired 本质上是用来初始化对象的,(源城时好像是用来初始化实体类,捷顺用来初始化Dao层对象)

@Autowired默认按类型装配

注:捷顺用来初始化Dao层对象,关键是怎么和Mapper连接呢,有两种方案:

  • 在Dao层接口类上 写 @Mapper 注解,表示这个接口要对接mapper文件
  • 在application.xml中 添加配置:
<!-- 自动扫描了所有的XxxxMapper.java,这样就不用一个一个手动配置Mpper的映射了,只要Mapper接口类和Mapper映射文件对应起来就可以了 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.jieshun.jht.integral.dao" />
</bean>

来自 http://www.cnblogs.com/zghull/archive/2012/06/27/2565480.html

二 @Resource

这个是用来初始化对象的,这和@Autowired注解不一样,

  • @Autowired默认按类型装配 ,
  • @Resource按名称装配,

这是使用注解是要自己写名称的,捷顺在Controller里用初始化对象,使用这个注解,在接口实现类(impl)上使用注解 @Service(“mebershipService”)来表示这个类要放入IOC中,并指定名字,然后使用这个指定的名字就能获得对象,

如果没有指定名字就会按类型装配

来自 http://www.cnblogs.com/zghull/archive/2012/06/27/2565480.html

三 @Service

当你需要定义某个类为一个bean,则在这个类的类名前一行使用@Service(“XXX”),就相当于讲这个类定义为一个bean,bean名称为XXX;

会配合@Resource来使用

来自 http://www.cnblogs.com/Struts-pring/p/4951661.html

四 @Async

用法: 在方法上或者类上标注, 这样调用方法时就会异步执行, 它需要搭配 @EnableAsync注解使用

它还有一个value值,表示指定使用哪个线程池,不指定就用叫’taskExecutor’的线程池, 连默认线程池都没有就注解自己的线程池(有内存泄露风险,而且不重用线程)

原理: Spring容器启动初始化bean时,判断类中是否使用了@Async注解,创建切入点和切入点处理器,根据切入点创建代理,在调用@Async注解标注的方法时,会调用代理,执行切入点处理器invoke方法,将方法的执行提交给线程池,实现异步执行。

需要注意的一个错误用法是,如果A类的a方法(没有标注@Async)调用它自己的b方法(标注@Async)是不会异步执行的,因为从a方法进入调用的都是它本身,不会进入代理。(称为本地调用)

mode=AdviceMode.ASPECTJ 指定切面模式就可以生效

Spring @Async之四:Aysnc的异步执行的线程池实现原理 - duanxz - 博客园 (cnblogs.com)

Spring @Async 注解的使用以及原理(一)灵颖桥人的博客-CSDN博客@async注解

@Import

@Import注解可以用于导入第三方包 ,当然@Bean注解也可以,但是@Import注解快速导入的方式更加便捷.Import注解本身在springboot中用的很多,特别是ImportSelector方式在springboot中使用的特别多

@Import的三种用法

@Import的三种用法主要包括:

  1. 直接填class数组方式
  2. ImportSelector方式【重点】
  3. ImportBeanDefinitionRegistrar方式

第一种用法:直接填class数组

直接填对应的class数组,class数组可以有0到多个。

语法如下:

@Import({ 类名.class , 类名.class... })
public class TestDemo {

}

对应的import的bean都将加入到spring容器中,这些在容器中bean名称是该类的全类名 ,比如com.yc.类名

第二种用法:ImportSelector方式【重点】

这种方式的前提就是一个类要实现ImportSelector接口,假如我要用这种方法,目标对象是Myclass这个类,分析具体如下:

创建Myclass类并实现ImportSelector接口

public class Myclass implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        // 特意换个bean名字
        return new String[]{"com.yc.Test.TestDemo3"};
    }
}

分析实现接口的selectImports方法中的:

  • 1、返回值: 就是我们实际上要导入到容器中的组件全类名【重点
  • 2、参数: AnnotationMetadata表示当前被@Import注解给标注的所有注解信息【不是重点】

需要注意的是selectImports方法可以返回空数组但是不能返回null,否则会报空指针异常!

案例:

@Import({TestDemo2.class,Myclass.class})
public class TestDemo {
        @Bean
        public AccountDao2 accountDao2(){
            return new AccountDao2();
        }

}

/**
 * 打印容器中的组件测试
 */
public class AnnotationTestDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(TestDemo.class);  //这里的参数代表要做操作的类

        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String name : beanDefinitionNames){
            System.out.println(name);
        }

    }
}

所以初始化TestDemo类时就会有三个对象被初始化

在这里插入图片描述

第三种用法:ImportBeanDefinitionRegistrar方式

同样是一个接口,类似于第二种ImportSelector用法,相似度80%,只不过这种用法比较自定义化注册,具体如下:

public class Myclass2 implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        //指定bean定义信息(包括bean的类型、作用域...)
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestDemo4.class);
        //注册一个bean指定bean名字(id)
        beanDefinitionRegistry.registerBeanDefinition("TestDemo4444",rootBeanDefinition);
    }
}

spring注解之@Import注解的三种使用方式 - 宜春 - 博客园 (cnblogs.com)