【SpringBoot】注解编程

一、SpringBoot注解

1、Spring 1.x

@Transaction

@Transaction只能应用到接口方法、类、还有public方法上,用于管理事务的一种重要工具。在应用程序中,一次事务可能包括多个对数据库的读写操作。@Transaction 注解可以确保这些操作要么全部成功,要么全部失败,从而保持数据的一致性。

2、Spring 2.x

@Required

@Required注解用于标记bean属性的setter方法(它只能应用于setter方法上),指示这些属性在配置时必须被显式地设置值或通过自动装配被填充。如果Spring容器在初始化bean时发现这些被@Required标记的属性未被赋值,则会抛出BeanInitializationException异常,从而确保bean的正确配置。

@Repository

它用来标注访问层的类(Dao层),它表示一个仓库,主要用于封装对于数据库的访问。其实现方式与@Component注解相同,只是为了明确类的作用而设立。

即@Repository是@Component注解的一个派生品,与@Service和@Controller都可以理解为@Component注解的扩展。他们的作用都是在类上实例化bean,并把当前类对象的实现类交给spring容器进行管理。

@Aspect

@Aspect是AOP相关的一个注解,用来标识配置类。

@Autowired 

@Autowired 用于自动装配bean,它可以被应用于构造函数、setter方法、具有任意名称或多个参数的属性上。@Autowired默认按照类型(byType)进行自动装配,这意味着Spring会尝试在容器中查找与属性或构造函数参数类型相匹配的bean,并将其注入。

@Qualifier

用于在存在多个相同类型的bean时,指定应该注入哪个确切的bean。它与@Autowired注解结合使用,通过bean的名称或标识符来消除自动装配时的歧义。

@Component

声明组件

@Service

声明业务层组件

@Controller

声明控制层组件

@RequestMapping

声明请求对应的处理方法

3、Spring 3.x

@ComponentScan

@ComponentScan的作用是指定扫码路径,用来替代在XML中的 <component-scan>标签,默认的扫码路径是当前注解标注的类所在的包及其子包。

当然也可以指定特定的扫描路径:

@Configuration
// 指定特定的扫描路径
@ComponentScan(value = {"com.yq.demo04"})
public class JavaConfig {

    public static void main(String[] args) {
        ApplicationContext ac = new AnnotationConfigApplicationContext(JavaConfig.class);
        System.out.println("ac.getBean(UserService.class) = " + ac.getBean(UserService.class));
    }
}

@Import

@Import注解只能用在类上,作用是快速的将实例导入到Spring的IoC容器中,将实例导入到IoC容器中的方式有很多种,比如 @Bean注解,@Import注解可以用于导入第三方包。具体的使用方式有三种。

静态导入

  静态导入的方式是直接将我们需要导入到IoC容器中的对象类型直接添加进去即可。

这种方式的好处是简单,直接,但是缺点是如果要导入的比较多,则不太方便,而且也不灵活。

ImportSelector

@Import注解中我们也可以添加一个实现了 ImportSelector接口的类型,这时不会将该类型导入IoC容器中,而是会调用 ImportSelector接口中定义的 selectImports方法,将该方法的返回的字符串数组的类型添加到容器中。

定义ImportSelector接口的实现,方法返回的是需要添加到IoC容器中的对象对应的类型的全类路径的字符串数组,我们可以根据不同的业务需求而导入不同的类型,会更加的灵活些。

ImportBeanDefinitionRegistrar

除了上面所介绍的ImportSelector方式灵活导入以外还提供了 ImportBeanDefinitionRegistrar 接口,也可以实现,相比 ImportSelector 接口的方式,ImportBeanDefinitionRegistrar 的方式是直接在定义的方法中提供了 BeanDefinitionRegistry ,自己在方法中实现注册。

@Enable模块驱动

@Enable模块驱动,其实是在系统中我们先开发好各个功能独立的模块,比如 Web MVC 模块, AspectJ代理模块,Caching模块等。@Enable模块驱动核心就是@Import注解

4、Spring 4.x

@Conditional

@Conditional 注解的作用是按照一定的条件进行判断,满足条件就给容器注册Bean实例。

// 该注解可以在 类和方法中使用
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {

    /**
     * 注解中添加的类型必须是 实现了 Condition 接口的类型
     */
    Class<? extends Condition>[] value();

}

/**
 * ConditionOnBean
 */
public class ConditionOnClass implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 根据我们特定的业务需求来决定是否注入对应的对象
        try {
            Class.forName("com.yq.test.test666");
            return true;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return false;
    }
}
@Configuration
public class Demo04JavaConfig {

    /**
     * @Conditional 条件注解
     *    控制对象是否注入到容器中
     * @return
     */
    @Conditional(ConditionOnClass.class)
    @Bean
    public DeptService deptService(){
        return new DeptService();
    }

    public static void main(String[] args) {
        ApplicationContext ac = new AnnotationConfigApplicationContext(Demo04JavaConfig.class);
        System.out.println(ac.getBean(DeptService.class));
    }
}

5、Spring 5.x

@Indexed

当我们在项目中使用了 @Indexed之后,编译打包的时候会在项目中自动生成 META-INT/spring.components文件。当Spring应用上下文执行 ComponentScan扫描时,META-INT/spring.components将会被 CandidateComponentsIndexLoader 读取并加载,转换为 CandidateComponentsIndex对象,这样的话 @ComponentScan不在扫描指定的package,而是读取 CandidateComponentsIndex对象,从而达到提升性能的目的。

@Component等注解中已经使用了@Indexed

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
    String value() default "";
}

二、SPI

SPI ,全称为 Service Provider Interface,是一种服务发现机制。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类。这一机制为很多框架扩展提供了可能,比如在Dubbo、JDBC中都使用到了SPI机制。

案例:
1、定义接口项目
package com.yq;

/**
 *  SPI 定义的公共接口
 *          只需要声明一个接口
 */
public interface MySPI {

    public void sayHello();

}
2、然后创建一个新项目,创建一个扩展的实现,先导入上面接口项目的依赖
    <dependencies>
        <dependency>
            <groupId>com.yq</groupId>
            <artifactId>MySPI</artifactId>
            <version>1.0-SNAPSHOT</version>
        <dependency>
    <dependencies>
3、创建接口的实现
package com.mysql;

import com.yq.MySPI;


/**
 * SPI:MySQL对于 MySPI 的一种实现
 */
public class MySQLSPI implements MySPI {

    @Override
    public void sayHello() {
        System.out.println("Hello, I am MySQLSPI");
    }
}

然后在resources目录下创建 META-INF/services 目录,然后在目录中创建一个文件,名称必须是定义的接口的全类路径名称。然后在文件中写上接口的实现类的全类路径名称。

4、再创建一个oracle案例
package com.oracle;

import com.yq.MySPI;

/**
 * SPI:oracle 对于 MySPI 的一种实现
 */
public class OracleSPI implements MySPI {
    @Override
    public void sayHello() {
        System.out.println("Oracle SPI");
    }
}

5、创建测试项目
package com.yq;

import java.util.Iterator;
import java.util.ServiceLoader;

public class StartApp {
    public static void main(String[] args) {
        //启动程序
        ServiceLoader<MySPI> load = ServiceLoader.load(MySPI.class);
        Iterator<MySPI> iterator = load.iterator();
        while(iterator.hasNext()){
            MySPI con = iterator.next();
            con.sayHello();
        }
    }
}
6、对于不同的依赖引入,会有不同的输出

7、源码查看:ServiceLoader
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值