RunnableDemo类
package com.boot.enable.bootenable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public 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
@EnableAsync
public 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;
@Component
public 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;
/**
* 普通方式装配
*/
@SpringBootApplication
public 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;
@Component
public class Person {
}
public class Person1 {
}
package com.boot.enable.sample.bean;
import org.springframework.stereotype.Component;
@Component
public class Person2 {
}
package com.boot.enable.sample.vo;
import org.springframework.stereotype.Component;
@Component
public 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未加注解,所以未打印)
监控器流程图解