使用注解实现异步
RunnableDemo类
package com.boot.enable.bootenable;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Component;import java.util.concurrent.TimeUnit;@Componentpublic class RunnableDemo implements Runnable { @Async // 异步方式执行方法 public void run() { for (int i = 0; i < 10; i++) { System.out.println("----------------"+ (i +1)); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }}
测试类
package com.boot.enable.bootenable;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.scheduling.annotation.EnableAsync;@SpringBootApplication@EnableAsyncpublic class BootEnableApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(BootEnableApplication.class, args); Runnable bean = context.getBean(Runnable.class); System.out.println("-----------start-----------"); bean.run(); System.out.println("-----------end-----------"); context.close(); }}
运行结果分析:
run方法打印的内容是异步进行的,是独立于主线程外的线程,所以-----------end-----------打印后,run方法依然再进行打印
几种装配方式
1.普通的方式
package com.boot.enable.imp.demo;public class Book {}
package com.boot.enable.imp.demo;import org.springframework.stereotype.Component;@Componentpublic class User {}
package com.boot.enable.imp.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.Bean;/** * 普通方式装配 */@SpringBootApplicationpublic class ImportApplication { @Bean public Book book() { return new Book(); } public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(ImportApplication.class, args); System.out.println(context.getBean(User.class)); System.out.println(context.getBean(Book.class)); context.close(); }}
使用@Import装配的第一种方式
package com.boot.enable.imp.demo1;public class Book {}
package com.boot.enable.imp.demo1;public class User {}
package com.boot.enable.imp.demo1;import org.springframework.context.annotation.ImportSelector;import org.springframework.core.type.AnnotationMetadata;public class BeanImportSelector implements ImportSelector {//不需要注入其他属性时使用 @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { return new String[]{"com.boot.enable.imp.demo1.Book" ,"com.boot.enable.imp.demo1.User"}; }}
package com.boot.enable.imp.demo1;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.Import;/** * 使用@Import方式装配 */@SpringBootApplication// @Import({User.class, Book.class})@Import(BeanImportSelector.class)public class ImportApplication1 { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(ImportApplication1.class, args); System.out.println(context.getBean(User.class)); System.out.println(context.getBean(Book.class)); context.close(); }}
使用@Import装配 第二种方式
package com.boot.enable.imp.demo2;import org.springframework.beans.factory.config.BeanDefinition;import org.springframework.beans.factory.support.BeanDefinitionBuilder;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;import org.springframework.core.type.AnnotationMetadata;public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {//有属性注入时使用 @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { // 创建构建器对象 BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(User.class); BeanDefinition beanDefinition = bdb.getBeanDefinition(); registry.registerBeanDefinition("user", beanDefinition); BeanDefinitionBuilder bdb1 = BeanDefinitionBuilder.rootBeanDefinition(Book.class); BeanDefinition beanDefinition1 = bdb1.getBeanDefinition(); registry.registerBeanDefinition("book", beanDefinition1); }}
package com.boot.enable.imp.demo2;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.context.annotation.Import;/** * 使用@Import方式装配 */@SpringBootApplication@Import(MyBeanDefinitionRegistrar.class)public class ImportApplication1 { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(ImportApplication1.class, args); System.out.println(context.getBean("user",User.class)); System.out.println(context.getBean(Book.class)); context.close(); }}
实例演示:注解注册监控器实现
实体类准备:
package com.boot.enable.sample.bean;import org.springframework.stereotype.Component;@Componentpublic class Person {}
public class Person1 {}
package com.boot.enable.sample.bean;import org.springframework.stereotype.Component;@Componentpublic class Person2 {}
package com.boot.enable.sample.vo;import org.springframework.stereotype.Component;@Componentpublic class UserVO {}
自定义一个注解(借用@Import机制)
package com.boot.enable.sample;import org.springframework.context.annotation.Import;import java.lang.annotation.*;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(ScannerPackageRegistrar.class)public @interface EnableScanner { String[] packages();}
package com.boot.enable.sample;import org.springframework.beans.factory.support.BeanDefinitionBuilder;import org.springframework.beans.factory.support.BeanDefinitionRegistry;import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;import org.springframework.core.type.AnnotationMetadata;import java.util.Arrays;import java.util.List;public class ScannerPackageRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { String[] attrs = (String[]) importingClassMetadata .getAnnotationAttributes(EnableScanner.class.getName()) .get("packages");//获取到注解的packages属性 List<String> packages = Arrays.asList(attrs); System.out.println(packages); BeanDefinitionBuilder bdb = BeanDefinitionBuilder.rootBeanDefinition(MyBeanDefinitionProcessor.class); bdb.addPropertyValue("packages", packages);//注入属性 registry.registerBeanDefinition(MyBeanDefinitionProcessor.class.getName(), bdb.getBeanDefinition());//装配到Spring容器中 }}
package com.boot.enable.sample;import org.springframework.beans.BeansException;import org.springframework.beans.factory.config.BeanPostProcessor;import java.util.List;public class MyBeanDefinitionProcessor implements BeanPostProcessor { private List<String> packages; public List<String> getPackages() { return packages; } public void setPackages(List<String> packages) { this.packages = packages; } @Override//扫描出装配到容器中的类并打印出对应实例 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { for (String pack : packages) { if (bean.getClass().getName().startsWith(pack)) { System.out.println("instance bean:"+bean.getClass().getName()); } } return bean; }}
测试类
package com.boot.enable.sample;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;/** * 普通方式装配 */@SpringBootApplication@EnableScanner(packages ={"com.boot.enable.sample.bean","com.boot.enable.sample.vo"}) // 启用监控扫描类的注解public class ScannerPackageApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(ScannerPackageApplication.class, args); context.close(); new ScannerPackageApplication().callFunction(new FunctionImpl());//回调演示 } interface Function { void hello(); } static class FunctionImpl implements Function { @Override public void hello() { System.out.println("调用了FunctionImpl->Hello方法"); } } public void callFunction(Function fun) {
//处理其他事 fun.hello(); //回调
//处理其他事 }}
打印结果(打印出注入到Spring容器中的实例,Person1未加注解,所以未打印)
监控器流程图解
还没有人抢沙发呢~