一、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、对于不同的依赖引入,会有不同的输出


1871

被折叠的 条评论
为什么被折叠?



