spring注解开发
😁一、组件注册
🍎一、给容器中注册组件
创建一个java类
@Configuration : 说明这是一个配置类
@Bean : 给容器中注册一个bean对象
@Configuration
publi class MyConfig{
@Bean("per")
public Person person(){
return new Person("张三", 23);
}
}
测试类
public class MyTest{
@Test
public void testConfig(){
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
Person person = context.getBean(Person.class);
System.out.println(person);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println("beanDefinitionName = " + beanDefinitionName);
}
}
}
🍊二、自动扫描组件
@ComponentScan
相当于配置文件的context component-scan base-package=""
属性
excludeFilters : 设置要排除的规则
@ComponentScan(value="", excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes = {Controller.class, Service.class})})
设置排除的规则为注解类型,排除的注解为@Controller和@Service的类文件
includeFilters : 设置要包含的规则,使用方法类似excluedeFilters,但是作用正好相反
@Configuration
@ComponentScan("com.wyxz.spring")
public class MyConfig{
@Bean
public Person person() {
return new Person("张三", 23);
}
}
测试
public class MyTest{
@Test
public void testConfig(){
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println("beanDefinitionName = " + beanDefinitionName);
}
}
}
@ComponentScans 可以配置多个@componentScan
自定义TypeFilter 过滤规则
public class MyTypeFilter implements TypeFilter {
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
ClassMetadata classMetadata = metadataReader.getClassMetadata();
Resource resource = metadataReader.getResource();
String className = classMetadata.getClassName();
return false;
}
}
在配置类的@ComponentScan中的Filter中的class属性中
@ComponentScan(value="", excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes = {Controller.class, Service.class, MyTypeFilter.class})})
🍌三、设置组件作用域
@scope
相当于在配置文件中bean 中设置scope的作用域
@Configuration
@ComponentScan(value = {"com.wyxz.spring"},
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes = {Controller.class, Service.class})})
public class MyConfig {
@Bean
@Scope(value = "prototype")
public Person person() {
return new Person("张三", 23);
}
}
🍉四、懒加载
@Lazy :让容器启动的时候先创建对象并初始化,懒加载只针对于单实例
@Configuration
@ComponentScan(value = {"com.wyxz.spring"},
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes = {Controller.class, Service.class})})
public class MyConfig {
@Bean
@Scope(value = "sinleton")
@Lazy
public Person person() {
return new Person("张三", 23);
}
}
🍓五、按照条件注册
@Conditional
@Configuration
@ComponentScan(value = {"com.wyxz.spring"},
excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION,
classes = {Controller.class, Service.class})})
public class MyConfig {
@Conditional({WindowsCondition.class})
@Bean("bill")
public Person bill(){
return new Person("bill gates",60);
}
@Conditional({LinuxCondition.class})
@Bean("linus")
public Person linus(){
return new Person("linus", 48);
}
}
自定义条件
public class WindowsCondition implements Condition{
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String osName = environment.getProperty("os.name");
if(osName.contains("Windows")){
return true;
}
return false;
}
}
public class LinuxCondition implements Condition {
public boolean matches(ConditionContext context, AnnotatedTypemetadata metadata) {
Environment environment = context.getEnvironment();
String osName = environment.getProperty("os.name");
if(osName.contains("lin")){
return true;
}
return false;
}
}
🍇六、给容器中导入组件
@import
publi class Color{}
@Import(value = {Color.class})
@Configuration
public class MyConfig {
}
ImportSelector
需要实现这个接口,实现其中的方法
publi class MyImport implements ImportSelector {
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.wyxz.spring.Blue"};;
}
}
@Import(value = {Color.class, MyImport.class})
@Configuration
public class MyConfig {
}
registerBeanDefinitions : 实现这个接口
public class MyImportDefinition implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean beanDefinition = registry.containsBeanDefinition("com.wyxz.spring.Color");
if (beanDefinition){
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Blue.class);
registry.registerBeanDefinition("blue",rootBeanDefinition);
}
}
}
@Import({Color.class, MyImport.class, MyImportDefinition.class})
@Configuration
public class MyConfig {}
🍑七、使用工厂bean
FactoryBean 实现这个接口,并实现其中方法
public class ColorFactory implements FactoryBean<Color> {
public Color getObject() throws Exception {
return new Color();
}
public Class<?> getObjectType() {
return Color.class;
}
}
在配置类中注册
@Configuration
public class MyConfig {
@Bean
public ColorFactory colorFactory(){
return new ColorFactory();
}
}
如果想要获取到工厂bean,可以在获得factorybean的实例前加一个"&"
😊二、组件生命周期
实现InitializingBean接口实现初始化
实现DisposableBean接口实现销毁方法
public class Car implements InitializingBean, DisposableBean {
public void afterPropertiesSet() throws Exception {
}
public void destroy() throws Exception {
}
}
@PostConstruct :在bean创建完成并属性赋值完成之后执行
@PreDestroy : 在容器销毁bean之前执行
🍅一、后置处理器
BeanPostProcessor
😒三、属性赋值
🥒一、使用value为属性赋值
@Value 注解设置在属性上边可以为属性赋值,当spring在加载容器的时候能获取到值
public class User {
@Value("张三")
private String name;
@Value("#{30-9}")
private Integer age;
@Value("${email}")
private String email;
}
email=123@163.com
在配置类上添加注解
@Configuration
@PropertySource(value = {"classpath:user.properties"})
public class MyConfig{}
🍆二、自动注入
@Autowired :按照类型查找容器组件,找到之后赋值
@Qualifier : 指定要装配的组件的id(组合注解,和@Autowired 搭配)
@Primary :在进行自动装配中使用默认首选的(组合注解,和@Autowried 搭配)
@Resource : 相当于@Autowired 的注入方式,但是@Resource 是java提供的注解,而@Autowired 是spring提供的注解,按照名称进行装配
@Inject : 相当于@Autowired 的注入方式,需要导入jar包javax inject
🍉三、自定义组件调用底层spring组件
需要实现继承了Aware接口的接口,重写其中的方法
每一个Aware接口的接口都有相对应的processor后置处理器
public class Red implements ApplicationContextAware {
}
🍐四、
@Profile : 动态激活某一个组件,指定组件在哪个情况下才能被注册到容器中
@Configuration
@PropertySource("classpath:jdbc.properties")
public class MyConfig {
@Value("${username}")
private String username;
@Value("${password}")
private String password;
@Bean("devDataSource")
@Profile("dev")
public DataSource dataSource(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(username);
dataSource.setPassword(password);
dataSource.setUrl("");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
return dataSource();
}
@Bean("testDataSource")
@Profile("test")
public DataSource dataSource(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(username);
dataSource.setPassword(password);
dataSource.setUrl("");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
return dataSource();
}
@Bean("productDataSource")
@Profile("product")
public DataSource dataSource(){
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(username);
dataSource.setPassword(password);
dataSource.setUrl("");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
return dataSource();
}
}
激活某一个环境
- 在命令行设置启动参数:
vm options 中-Dspring.profiles.active =要使用的环境 - 在类中设置启动环境
public class Test {
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.getEnvironment().setActiveProfiles("test","dev");
applicationContext.register(MyConfig.class);
applicationContext.refresh();
}
}
😉四、面向切面编程
@Before : 在想要执行的方法执行之前执行该方法
@After : 在想要执行的方法执行之后执行的方法
@AfterReturning : 在想要执行的方法执行正常返回之后执行的方法
@AfterThrowing : 当要执行的方法抛出异常后执行该方法
@Around : 当要执行的方法执行前后都执行该方法
public class AspectLog {
@Before()
public void before(){}
@After()
public void after(){}
@AfterReturning()
public void afterReturn(){}
@AfterThrowing()
public void afterThrow(){}
@Around()
public void around(){}
}
public class Calculator {
public int add(int a, int b){
return a + b;
}
}
将所有执行的类注册到配置类中
再配置类中添加注解
再配置类中开启切面功能@EnableAspectJAutoProxy
@Configuration
@EnableAspectJAutoProxy
@Aspect
public class MyConfig {
@Bean
public Calculator calculator(){
return new Calculator();
}
@Bean
public AspectLog aspectLog(){
return new AspectLog();
}
}
在测试类中使用
public class Test {
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
Calculator calculator = applicationContext.getBean(Calculator.class);
calculator.add(1, 1);
}
}
一个切面类 public class MyConfig { @Bean public Calculator calculator(){ return new Calculator(); } @Bean public AspectLog aspectLog(){ return new AspectLog(); } }
在测试类中使用
```java
public class Test {
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
Calculator calculator = applicationContext.getBean(Calculator.class);
calculator.add(1, 1);
}
}
|