@Autowired 引发的一系列思考
2024-09-07 04:57:15
关于Java注解
注解定义
- 标记注解 - 没有元素
@interface Marker {
}
- 单元素注解 - 只有一个元素
@interface Single {
String value() default "name";
}
- 普通注解 - 除了上面两种
@interface Normal {
String id();
String name();
}
@interface NormalWithValue {
String id() default "id";
String value();
}
注解使用
1. 标记注解 由 @Marker() 可以简化为 @Marker
2. 按照约定,单元素注解的名称定义为 value ,这样 Single(value="123") 可以简化为 @Single("123")
3. 对于普通注解,必须给出注解中名称以及对应的值,当然有默认值的除外,如果普通注解含有 value 名称,并且其他名称都有默认值,也可以简化为 @Normal("123")
实例如下:
@Marker
@Single("123")
@Normal(id = "123", name = "123")
@NormalWithValue("123")
class AnnotationMain {
}
Spring 中的注解
- 元注解(Meta-Annotations)
在另一个注解上声明的注解,所以说任何一个注解都可以成为元注解
在下面这个例子中,@Target、@Retention、@Documented、@Indexed都是元注解
如果@Component又跑到别的注解头上了,那它也是元注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
}
- 角色注解(Stereotype Annotations)
代表着一种固有的形象
比如@Component代表组件,@Repository代表DAO,@service代表服务等等
- 组合注解(Composed Annotations)
将一个或多个注解注解到一个注解上
在Spring中,注解上的任何一个注解都是可以被感知到的,就代表这个注解拥有了上述几个注解的所有功能
在下面这个例子中,@EnableAutoConfiguration组合了@AutoConfigurationPackage和@Import
使用@EnableAutoConfiguration的类会被Spring认为@EnableAutoConfiguration和@AutoConfigurationPackage也是存在的
因此@EnableAutoConfiguration就具备了@AutoConfigurationPackage的功能以及@Import的功能
这个实现好像是通过缓存实现的,具体也不太了解,有大佬知道的可以在评论里告知一下~
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}
Spring-Annotation-Programming-Model
MergedAnnotation-API-internals
Spring中的 @Autowired
,一个自动注入的注解
- 可以在构造函数中注入
@Service
@Getter
public class MyService1 {
private MyDao1 myDao1;
@Autowired
public MyService1(MyDao1 myDao1) {
this.myDao1 = myDao1;
}
}
- 可以在方法中注入
Spring 会自动自动执行方法,并把myDao注入住到方法参数里面
@Getter
public class MyService2 {
private MyDao1 myDao1;
private MyDao2 myDao2;
@Autowired
public void setMyDao1(MyDao1 myDao1) {
this.myDao1 = myDao1;
}
@Autowired
public void fun(MyDao2 myDao2) {
this.myDao2 = myDao2;
}
}
- 也可以在属性上注入
@Getter
public class MyService3 {
@Autowired
private MyDao1 myDao1;
}
- 也可以混合注入
@Getter
public class MyService4 {
@Autowired
private MyDao1 myDao1;
private MyDao2 myDao2;
private MyDao3 myDao3;
@Autowired
public void fun(MyDao2 myDao2) {
this.myDao2 = myDao2;
}
@Autowired
public MyService4(MyDao3 myDao3) {
this.myDao3 = myDao3;
}
}
- 其他注意的地方
- 使用
@Autowired
时,容器里必须要存在这个类型的实例的,如果没有就会报错,如果不是必须要注入此类,可以将required
设置为false
,默认为true
@Getter
public class MyService5 {
private MyDao1 myDao1;
@Autowired(required = false)
public MyService5(MyDao1 myDao1) {
this.myDao1 = myDao1;
}
}
- 如果在多个构造函数上使用
@Autowired
,则所有的@Autowired
必须将required
设置为false
,将会选一个参数较多的构造函数进行注入
@Getter
public class MyService6 {
private MyDao1 myDao1;
private MyDao2 myDao2;
@Autowired(required = false)
public MyService6() {
}
@Autowired(required = false)
public MyService6(MyDao1 myDao1) {
this.myDao1 = myDao1;
}
@Autowired(required = false)
public MyService6(MyDao2 myDao2) {
this.myDao2 = myDao2;
}
}
- 如果只有一个构造函数,不用加
@Autowired
也会自动注入,下面的例子中的所有属性将会注入
@Getter
public class MyService6 {
private MyDao1 myDao1;
private MyDao2 myDao2;
public MyService6(MyDao1 myDao1, MyDao2 myDao2) {
this.myDao1 = myDao1;
this.myDao2 = myDao2;
}
}
使用Java编程获取Spring bean
@Bean
用于标记一个bean
定义@Configuration
里面有很多@Bean
标记的方法
public class MyDao {
}
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class MyService {
private MyDao myDao;
}
@Configuration
public class AppConfig {
@Bean
public MyService myService(MyDao myDao) {
return new MyService(myDao);
}
@Bean
public MyDao myDao() {
return new MyDao();
}
}
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = applicationContext.getBean(MyService.class);
MyDao myDao = applicationContext.getBean(MyDao.class);
System.out.println(myService.getMyDao() == myDao);
}
}
输出:
true
说明 myService不为null,myDao不为null,myDao已经被注入到myService中
最新文章
- hdu 2191 完全背包
- 【secureCRT】如何在secureCRT上设置常用的快捷输出按钮栏
- 教育行业SaaS选型 需要注意的三点问题
- 使用mysql作为hive的元数据库
- Cmake,source_group
- 微信小程序数据请求方法wx.request小测试
- [H5]API之range对象
- win10 uwp 应用转后台清理内存
- flask 动手写的接口平台
- SQLite 的 EXISTS 与 NOT EXISTS
- ASP.NET Zero--Migration控制台应用程序
- 《DOM Scripting》学习笔记-——第七章 动态创建html内容
- 黄聪:C# webBrowser控件禁用alert,confirm之类的弹窗解决方案
- hive类型转化错误,会错误提示指定分区参数
- MetaMask/zero-client
- 关于QT中“崩溃”问题
- MySQL ZIP Archive 5.7.17 安装方法
- scala实现彩票算法
- VMware Workstation中虚拟机的克隆
- 参加SAP VT项目有感