# 注解实现 IoC
将类的创建交给我们配置的 JavaConfig
类完成,Spring 只负责维护和管理,本质上就是把 XML 配置声明转移到 Java 配置类中。
因为创建交给 Java 代码,所以我们在类创建的时候可以执行更多的操作,纯 Java 代码,扩展性高,十分灵活。
创建一个配置类,添加 @Configuration
注解声明为注解类;在配置类中编写返回 Bean 对象的方法,加上 @Bean
注解,该实例创建后会交给 spring 管理:
@Configuration | |
public class MyConfiguration { | |
@Bean | |
@Scope("prototype") | |
public Student student() { | |
// 也可以是 @Bean ("xxxx") | |
// 方法名建议与实例名相同(首字母小写) | |
return new Student(); | |
// return new Student("name"); | |
} | |
} |
创建出来的 Bean
对象还是默认单例模式,所以可以通过 @Scope
注解修改。
下面讲的其实就是注解配置,上面的是 Java 配置,最开始的是 xml 配置。
也可以删除这些 bean
方法,直接在类上面使用 @ComponentScan("包")
来自动扫描:
@ComponentScan("com.bean") | |
@Configuration | |
public class MyConfiguration { | |
} |
在这种情况下, bean
类需要加上 @Component
才可以,配置类就是扫描给定包下面的 Component
。
@Component | |
@Scope("prototype") | |
@Setter | |
public class Student { | |
// .... | |
} |
其实可用的还有
@Controller
,@Service
等,他们和@Component
是一样的,只不过在 MVC 架构下,不同 bean 承担不同角色,使用对应的注解可以提高可读性。
# 自动装配
@Resource
注解:
现 Student
类中有一个属性是 private Card card
,就可以在属性上使用该注解,Spring 就会自动注入(在容器中查找)
@Component | |
public class Student { | |
// 不需要 set 方法 | |
@Resource | |
Card card; | |
/** | |
也可以是: | |
@Resource | |
public void setCard (Card card) { | |
this.card = card; | |
} | |
*/ | |
} |
@AutoWired
注解:
和上面那个一样的,但是不推荐使用在属性上,可以使用在构造方法,set 方法和方法参数上。
@ComponentScan("com.bean") | |
@Configuration | |
public class MainConfiguration { | |
@Bean | |
public Student student(@Autowired Card card){ | |
Student student = new Student(); | |
student.setCard(card); | |
return student; | |
} | |
} |
之前通过 xml
配置,可以指定 init-method
和 destroy
,这里可以使用 @PostConstruct
和 @PreDestroy
注解。
# 注解实现 AOP
回忆之前 AOP 的内容,主要是切点,切面,通知。
- 开启 AOP 注解,需要在配置类加上
@EnableAspectJAutoProxy
:
@EnableAspectJAutoProxy | |
public class MainConfiguration { | |
} |
- 还是在
Student
类找切入点,假设是study
方法
@Data | |
@Component | |
public class Student { | |
// ... | |
public void study() { | |
System.out.println(name + " is studying..."); | |
} | |
} |
- 定义切面类,这点是和 xml 配置一样的(只是里面的方法,也就是通知需要加上注解)。我们需要这么一个类,因为 AOP 就是将分散在各个业务逻辑代码中相同的代码通过横向切割的方式抽取到一个独立的模块中!
@Component | |
@Aspect | |
public class AopTest { | |
@Before("execution(* com.bean.Student.study())") | |
public void before() { | |
System.out.println("Student.study()前置通知"); | |
} | |
// 也可以加上 JoinPoint | |
@After("execution(* com.bean.Student.study())") | |
public void after(JoinPoint point) { | |
System.out.println("切点方法参数列表:" + Arrays.toString(point.getArgs())); | |
System.out.println("Student.study()后置通知"); | |
} | |
} |
# 参考
https://pdai.tech/md/spring/spring-x-framework-ioc.html#java - 配置
https://www.yuque.com/qingkongxiaguang/spring/rlgcf7#fdba2fec