spring注解开发

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);
        // 获取到所有的bean容器对象实例
        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(){
        // 获取到所有的bean容器对象实例
        String[] beanDefinitionNames = context.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println("beanDefinitionName = " + beanDefinitionName);
        }
    }
}

@ComponentScans可以配置多个@componentScan

自定义TypeFilter过滤规则

public class MyTypeFilter implements TypeFilter {
    /**
     * 
     * @param metadataReader 读取到当前正在扫描的类的信息
     * @param metadataReaderFactory 可以获取到其他任何类的信息
     * @return
     * @throws IOException
     */
    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
    // prototype 每次获取的时候才会调用
    // singleton 每次获取直接从容器中拿
    @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
    // prototype 每次获取的时候才会调用
    // singleton 每次获取直接从容器中拿
    @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 {
	/**
     * 当在Windows系统的使用加载bill,在linyx上加载linus
     * @return
     */
    @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
// 读取到外部配置文件,相当于xml配置文件中<context:property-placeholder location="classpath:user.properties" />
@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();
    }
}

激活某一个环境

  1. 在命令行设置启动参数:vm options-Dspring.profiles.active=要使用的环境
  2. 在类中设置启动环境
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);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农先生eee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值