使用@Autowired实现工厂模式

首先一个大前提,这些“商品”都有统一的标准和行为(因为不知道具体要的哪个实现类,所以要有个抽象类或者接口,因此需要统一的标准和行为)。
所以首先设计抽象类或者接口

public abstract class Animal {
    private String name ="animals";
    //getName()和say()可以写成抽象的,但是这么写可以保证即使拿不到对应的产品,也有默认的方法实现。
    public void say(){
        System.out.println(name);
    }

    public String getName() {
        return name;
    }
}

对应的Bean

//这里使用@Component是要配合@Autowried实现,所以要先注入到Spring容器中。
@Component
public class Cat extends Animal{
	//赋初值Cat
    @Value("Cat")
    private String name;
    //替换掉父类中getName()方法
    public String getName() {
        return name;
    }
}
//同上
@Component
public class People extends Animal{
    @Value("People")
    private String name;
    public String getName() {
        return name;
    }

}

工厂实现

@Service
public class DeptServiceImpl {
    @Autowired
    DeptMapper deptMapper;
    @Autowired
    public void init(List<Animal> animals){
        for(Animal animal:animals){
            System.out.println(animal.getName());
        }
    }
   
}
@Service
public class DeptServiceImpl{
    @Autowired
    DeptMapper deptMapper;
    //存储对应的Bean
    public HashMap<String,Animal> beans = new HashMap<>();
    //Spring会将所有实现Animal的Bean都注入到List<Animal>里面来,然后通过beans 去接收,这里使用static是可以在别的地方也使用。
    @Autowired
    public void init(List<Animal> animals){
        for(Animal animal:animals){
            beans.put(animal.getName(),animal);
        }
    }
   
}

最后获取对应的Animals

@RestController
public class AnimalController {
    @Autowired
    DeptService deptService;
    @GetMapping("/{name}")
    public Animal getCat(@PathVariable("name") String name){
        return new JsonObject(deptService.getAnimal(name), CodeAndMsgEnum.success.getCodeAndMsg());
    }
}

最后看下效果
在这里插入图片描述
在这里插入图片描述
可以看到已经实现了工厂模式了,在该场景中,其实通过获取到不同的bean,也能通过say()方法执行对应的方法。所以这种工厂模式,其实也可以用来编写统一的Service层入口,然后再通过该入口执行对应的不同Service实现。 也可以用来实现一小部分统一的Service层的实现,总之根据业务需要,灵活使用。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对您的问题,我可以给您提供一些思路和代码实现。 首先,我们来看一下注解的定义: 1. @Component 该注解用于标注Bean,表示该类需要被IoC容器管理。 ``` @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Component { String value() default ""; } ``` 2. @Autowired 该注解用于标注需要被注入的对象,表示该对象需要从IoC容器中获取。 ``` @Target({ElementType.FIELD, ElementType.CONSTRUCTOR}) @Retention(RetentionPolicy.RUNTIME) public @interface Autowired { String value() default ""; } ``` 3. @Configuration 该注解用于标注为配置类,表示该类中定义的Bean需要被IoC容器管理。 ``` @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Configuration { String value() default ""; } ``` 接下来,我们来看一下IoC容器类的实现。我们可以定义一个AnnotationConfigApplicationContext类,其中包含一个Map用于存储Bean的定义和实例。 ``` public class AnnotationConfigApplicationContext { private Map<String, Object> beanMap = new HashMap<>(); public AnnotationConfigApplicationContext(Class<?> configClass) throws Exception { // 扫描所有的Component注解,并将类定义加入到beanMap中 scanComponents(configClass); // 处理所有的Autowired注解,并注入Bean依赖 injectDependencies(); } // 扫描所有的Component注解 private void scanComponents(Class<?> configClass) throws Exception { ComponentScan componentScan = configClass.getAnnotation(ComponentScan.class); if (componentScan != null) { String[] basePackages = componentScan.value(); for (String basePackage : basePackages) { String packagePath = basePackage.replace(".", "/"); URL url = Thread.currentThread().getContextClassLoader().getResource(packagePath); if (url == null) { continue; } File basePackageFile = new File(url.toURI()); for (File file : basePackageFile.listFiles()) { String fileName = file.getName(); if (fileName.endsWith(".class")) { String className = fileName.substring(0, fileName.lastIndexOf(".")); Class<?> clazz = Class.forName(basePackage + "." + className); Component component = clazz.getAnnotation(Component.class); if (component != null) { String beanName = component.value(); if (beanName.equals("")) { beanName = className.substring(0, 1).toLowerCase() + className.substring(1); } Object bean = clazz.getDeclaredConstructor().newInstance(); beanMap.put(beanName, bean); } } } } } } // 处理所有的Autowired注解 private void injectDependencies() throws Exception { for (Object bean : beanMap.values()) { for (Field field : bean.getClass().getDeclaredFields()) { Autowired autowired = field.getAnnotation(Autowired.class); if (autowired != null) { String beanName = autowired.value(); if (beanName.equals("")) { beanName = field.getType().getSimpleName().substring(0, 1).toLowerCase() + field.getType().getSimpleName().substring(1); } field.setAccessible(true); field.set(bean, beanMap.get(beanName)); } } } } // 获取Bean实例 public Object getBean(String beanName) { return beanMap.get(beanName); } } ``` 最后,我们来看一下如何使用该IoC容器。我们可以定义一个配置类,并在该类中定义需要被IoC容器管理的Bean。 ``` @Configuration @ComponentScan("com.example") public class AppConfig { @Component public class UserService { public void sayHello() { System.out.println("Hello, world!"); } } @Component public class UserController { @Autowired private UserService userService; public void sayHello() { userService.sayHello(); } } } ``` 然后,我们可以创建一个AnnotationConfigApplicationContext实例,并通过getBean方法获取Bean实例。 ``` public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); UserController userController = (UserController) context.getBean("userController"); userController.sayHello(); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值