Spring5学习(七)Spring注解

Spring注解开发

1. IOC相关注解

1.1 @Configuration

Spring3.0@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContextAnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

注意:@Configuration注解的配置类有如下要求:

  1. @Configuration不可以是final类型;

  2. @Configuration不可以是匿名类;

  3. 嵌套的configuration必须是静态类。

    @Configration注解同时被
    @Component注解修饰,因此具有被自动加载的特点,被@Configuration修饰的类本身也会作为definition注册。
    value属性是Configuration bean名称。

@Configuration //@Configuration 相当于applicationContext.xml配置文件
public class AppConfig {

}
public class SpringTest {
    //可以通过new AnnotationConfigApplicationContext(参数为@Configuration注解的类的class)
    @Test
    public void test1(){
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        System.out.println(applicationContext);
    }
}
1.2 @Bean

可以注解在方法上,容器会根据注解生成一个Bean对象。

1.3 @ComponentScan

作用在类上,声明需要对包路径下资源进行扫描,效果等同于<context:component-scan>

可以在一个类上多次使用@ComponentScan或者使用@ComponentScans注解,@ComponentScans可以包含多个@ComponentScan注解。

  • value: 属性指定要扫描的包路径,多个用逗号分割
  • excludeFilters:指定扫描的时候按照什么规则排除哪些组件。规则在@Filter中设置
  • includeFilters:指定扫描的时候只需要包含哪些组件。
  • useDefaultFilters:是否使用默认的规则。默认值true。
  • @ComponentScan.Filter:设置过滤规则

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H5VyE4OJ-1583204877986)(D:\TyporaDate\Spring\images\ComponentScan.png)]

//扫描
@ComponentScan(value="com.zm")
//设置排除规则
@ComponentScan(value = "com.zm",excludeFilters = {
        @ComponentScan.Filter(type=FilterType.ANNOTATION,classes = {Controller.class})
})
//设置包含规则,和useDefaultFilters一起使用排除默认的组件
@ComponentScan(value = "com.zm",includeFilters = {
        @ComponentScan.Filter(type=FilterType.ANNOTATION,classes = {Controller.class})
},useDefaultFilters = false)

@ComponentScan.Filter:

type:属性值为FilterType枚举类型的值。默认值为ANNOTATION

  • ANNOTATION: 注解类型,配合AnnotationTypeFilter使用,筛选出被指定注解修饰的资源
  • ASSIGNABLE_TYPE: 枚举出扫描类型,配合AssignableTypeFilter使用,加载指定类型的资源(含子类)
  • ASPECTJ: 用AspectJ表达式匹配资源。
  • REGEX: Java正则匹配资源
  • CUSTOM: 自定义的FIlter

classes:配合type一起使用,当type为

  • ANNOTATION:待扫描注解
  • ASSIGNABLE_TYPE:用户枚举的类
  • CUSTOM:自定义Filter

自定义Filter过滤规则

1.编写一个类,实现TypeFilter接口,在实现方法中定义Filtergui规则

public class MyTypeFilter implements TypeFilter {

    /**
     * MetadataReader metadataReader:获取当前正在扫描的类的信息
     * MetadataReaderFactory metadataReaderFactory,获取带其他任何类的信息
     *
     */
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();//获取当前类的注解信息
        ClassMetadata classMetadata = metadataReader.getClassMetadata();//获取当前扫描的类信息
        Resource resource = metadataReader.getResource();//获取当前扫描的资源信息
        String name = classMetadata.getClassName();//获取类的名字
        if(name.contains("er")) {
            return true;//如果类的名字中带有"er",则符合过滤的要求
        }
        return false;
    }
}

2.在注解类上@ComponentScan.Filter(type=FilterType.CUSTOM,classes = {MyTypeFilter.class})

@ComponentScan(value = "com.zm",includeFilters = {
        @ComponentScan.Filter(type=FilterType.CUSTOM,classes = {MyTypeFilter.class})
},useDefaultFilters = false)
1.4 @Scope

可以注解在类和方法,注解在类上默认对类里所有bean生效 。注解在方法中只对当前方法生成的Bean有效

value:指定bean的Scope。有singleton,prototype,request,session值,默认值为singleton。

​ singleton:单实例,在IOC容器启动后就创建该bean对象。

​ prototype:多实例,IOC容器启动不会创建该bean对象,在使用该bean时才会创建对象。

scopeName:设置scope的名称

proxyMode:设置生成的代理方式。值为ScopedProxyMode枚举类型中的值。默认值DEFAULT

DEFAULT、NO、INTERFACES(JDK方式)、TARGET_CLASS(CGLIB方式)

@Scope(value="singleton",proxyMode = ScopedProxyMode.DEFAULT)
1.5 @Lazy

注解可以用在类、方法、构造器、属性等。

value属性默认是true,使用@Lazy注解后默认就是延迟加载。

1.6 @Conditional

注解可以作用在类和方法上。作用在类上控制类中的所有bean按照条件判断注册。作用在方法身上控制方法中的bean按照条件进行注解。

value值为Condition[]。当value中有多个Condition时,必须所有的类返回条件为true,才会生成bean。

1、自定义一个类,实现org.springframework.context.annotation.Condition接口,重新匹配条件。

public class WindowsCondition implements Condition {
    /**
     * @param conditionContext:判断条件能使用的上下文环境
     * @param annotatedTypeMetadata:注解所在位置的注释信息
     * */
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        //获取ioc使用的beanFactory
        ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
        //获取类加载器
        ClassLoader classLoader = conditionContext.getClassLoader();
        //获取当前环境信息
        Environment environment = conditionContext.getEnvironment();
        //获取bean定义的注册类
        BeanDefinitionRegistry registry = conditionContext.getRegistry();

        //获得当前系统名
        String property = environment.getProperty("os.name");
        //包含Windows则说明是windows系统,返回true
        if (property.contains("Windows")){
            return true;
        }
        return false;
    }
}

2、在方法上使用@Conditional(value={自定义Condition类})

    @Conditional(value={WindowsCondition.class})
    @Bean(value="linus")
    public Person person02() {
        return new Person("linus", 48);
    }
1.7 @Import

注解作用在类上。value为Class[]数组

用法:

1. 直接写上需要注入的Bean的类型

@Import({Cat.class, Dog.class})

2. 通过ImportSelector方式注入Bean

​ 自定义类实现ImportSelector接口,在重写的方法中,将需要注入的bean的全类名放入到String[]中,然后在 @Import中加上自定义的类

public class MyImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        
        //将Employee类注入
        return new String[]{Employee.class.getName()};
    }
}
@Import({Cat.class, Dog.class, MyImportSelector.class})

3. 通过ImportBeanDefinitionRegistrar方式注入Bean

自定义类实现ImportBeanDefinitionRegistrar接口,在重写方法中注入bean信息

public class MyRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        BeanDefinition definition = new RootBeanDefinition(Country.class);
        //definition.setScope("singleton");
        //void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
        //beanName:给Bean对象设置名称
        //beanDefinition:设置bean的相关信息。可以设置scope,init-method等等信息
        registry.registerBeanDefinition("country",definition);
    }
}
@Import({Cat.class, Dog.class, MyImportSelector.class,MyRegistrar.class})
1.8 使用FactoryBean注入Bean

自定义一个类实现FactoryBean接口,重写方法。

//CatFactoryBean 用于创建Cat对象
public class CatFactoryBean implements FactoryBean<Cat> {
    @Override
    public Cat getObject() throws Exception {
        return new Cat();
    }

    @Override
    public Class<?> getObjectType() {
        return Cat.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}

//注入。实际创建的bean的类型是Cat.class
@Bean
public CatFactoryBean catBean(){
   return new CatFactoryBean();
}
1.9 Bean的生命周期

管理bean的生命周期

  1. @Bean中可以initMethod和destroyMethod值
    @Bean(initMethod = "init",destroyMethod = "destroy")
    public Teacher teacher(){
        return new Teacher();
    }

2.通过Bean实现InitializingBean, DisposableBean接口

public class Student implements InitializingBean, DisposableBean {

    @Override
    public void destroy() throws Exception {
        System.out.println("销毁destroy");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("初始化init");
    }
}

3.使用@PostConstruct和@PreDestroy注解

public class Lion {
    
    public Lion(){}
    
    @PostConstruct
    public void initmethod(){
        System.out.println("Lion...initmethod");
    }
    @PreDestroy
    public void destroymethod(){
        System.out.println("Lion...initmethod");
    }
}
1.10 @Controller @Service @Repository @Component

@Controller注解标注在Controller类上,@Service注解标注在Service的实现类上,@Repository注解标注在Dao的实现类上,@Component用于非Controller、Service、DAO类之外的类上,通用类。

在@Import中会自动扫描到标注了这些注解的类,主动注入到IOC 容器中。

1.11 @Value

修饰字段,方法,入参,实现属性注入 值。

1.12 @PropertySource

指定文件地址。提供了一种方便的、声明性的机制,用于向Spring的环境添加PropertySource。与@configuration类一起使用。

1.13 @Autowired @Qualifier @Primary

@Autowired:依赖注入,按照类型从容器中找对应的bean。如果容器中有多个相同类型的组件,再将属性的名称作为组件的id去容器中查找。可以设置required = false。

@Qualifier:和@Autowired组合使用,指定需要装配的组件的id。而不是使用属性名

@Primary :让spring自动装配的时候,默认使用首选的bean。

1.14 @Resource @Inject

@Resource: JSR-250提供的注解 。功能和@Autowired一样。默认按照属性名称查找注入

@Inject : JSR-330提供的注解 。功能和@Autowired一样,需要导入java.inject包。

1.15 @Profile

使用@Profile注解类或者方法,实现在不同情况下选择实例化不同的Bean。@Profile(“dev”)表示为dev时实例化。

@Profile("dev")

2. AOP相关注解

2.1 @EnableAspectJAutoProxy

注解@EnableAspectJAutoProxy表示开启代理。

proxyTargetClass:默认为false,表示使用jdk动态代理织入增强。proxyTargetClass设置为true,表示使用Cglib动态代理技术织入增强。proxyTargetClass设置为false,但是目标类没有声明接口,Spring aop还是会使用Cglib动态代理,也就是说非接口的类要生成代理都用Cglib。

  • Jdk代理:基于接口的代理,一定是基于接口,会生成目标对象的接口的子对象。
  • Cglib代理:基于类的代理,不需要基于接口,会生成目标对象的子对象。
2.2 @Aspect

注解在类上,表示该类是一个切面类。

2.3 通知
  • @Before() :
  • @After():
  • @AfterReturning() :
  • @AfterThrowing():
  • @Around():
@Pointcut("execution(* com.zm.service..*(..))")
    public void pointcut(){

    }

    @Before("execution(* com.zm.service..*(..))")
    public void before(JoinPoint jp){
        System.out.println("ArithmeticAspect..before()..");
    }


    @After("execution(* com.zm.service..*(..))")
    public void after(JoinPoint jp){
        System.out.println("参数为:"+Arrays.toString(jp.getArgs()));
        System.out.println("ArithmeticAspect..after()..");
    }

    @AfterReturning("pointcut()")
    public void afterReturning(){
        System.out.println("ArithmeticAspect..afterReturning()..");
    }

    @AfterThrowing("pointcut()")
    public void afterThrowing(){
        System.out.println("ArithmeticAspect..afterThrowing()..");
    }

    @Around("pointcut()")
    public void around(ProceedingJoinPoint pjp){
        try{
            pjp.proceed();
        }catch (Throwable throwable) {
            throwable.printStackTrace();
        } finally {

        }
    }
2.4 @Pointcut

通过注解**@Pointcut**定义切点,同一个类中的通知可以直接引用切点的方法名。不是同一个类中的引用需要加上全类名。

3. 事务相关注解

3.1 @EnableTransactionManagement

开启事务管理

3.2 @Transactional

事务,可以注解在类和方法上。注解在类上,表示该类的所有方法都需要事务控制,注解在方法上表示该方法需要事务控制。

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
    @AliasFor("transactionManager")
    String value() default "";

    @AliasFor("value")
    String transactionManager() default "";

    Propagation propagation() default Propagation.REQUIRED;

    Isolation isolation() default Isolation.DEFAULT;

    int timeout() default -1;

    boolean readOnly() default false;

    Class<? extends Throwable>[] rollbackFor() default {};

    String[] rollbackForClassName() default {};

    Class<? extends Throwable>[] noRollbackFor() default {};

    String[] noRollbackForClassName() default {};
}
属性名说明
name当在配置文件中有多个 TransactionManager , 可以用该属性指定选择哪个事务管理器。
propagation事务的传播行为,默认值为 REQUIRED。
isolation事务的隔离度,默认值采用 DEFAULT。
timeout事务的超时时间,默认值为-1。如果超过该时间限制但事务还没有完成,则自动回滚事务。
read-only指定事务是否为只读事务,默认值为 false;为了忽略那些不需要事务的方法,比如读取数据,可以设置 read-only 为 true。
rollback-for用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。
no-rollback- for抛出 no-rollback-for 指定的异常类型,不回滚事务。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值