IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> spring注解开发 -> 正文阅读

[Java知识库]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);
    }
}
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-21 20:35:37  更:2022-03-21 20:39:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:31:36-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码