模拟Spring IoC(二)Bean注解

本文探讨了Spring框架中Bean注解的使用场景,包括处理不可更改的类、无可用构造方法的类以及需要初始化配置的类。Bean注解克服了Autowired注解的局限性,适用于更多复杂场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在上一个博客中《模拟Spring IoC(一)Component及Autowired注解》中介绍了两个注解,Component注解和Autowired注解,下来就解释一下Bean注解。

Bean注解产生原因:

Autowired注解的缺陷:Autowired只能获取池子中的对象,而池中对象都是需要给对应的类以@Component注解;对于不可更改的Jar包中的类,就没有办法增加@Component注解,也就不能实现“注入”操作。Bean注解就是为了解决这样的问题存在的。

Bean注解:

@Retention(RUNTIME)
@Target(METHOD)
public @interface Bean {

}

Bean注解的使用场景

场景一
当我么需要注入的对象是一个不可更改的类时,需要使用Bean注解。比如,jar包中的类,众所周知,jar包中的类不能被更改,这就意味着不能给类增加Component注解,也就无法将该类以及成员装入容器中。而Bean注解就可以很好的解决这一点。

解决办法:创建一个配置类Config,在类中生成一个方法例如getComplex(),将该需要注入的类(类似jar包中的)作为方法返回值类型。给方法增加Bean注解,将这个方法的返回值对象和返回值对象类型封装到beanDefinition,以返回值类型名为键,beanDefinition对象为值存储到池子(map)中!(将Complex类和c对象存储到beanPool),如此就将jar包中类装入到了容器中。

下面Complex类,是自己编写的,导成了一个jar包

@Component
public class Config {
	@Bean
	public Complex getComplex() {
		System.out.println("将Complex这个不能更改的类,装入池子!");
		Complex c = new Complex(1.0, -3.0);
		c.setReal(c.getReal() + 2);
		
		return c;
	}
}	

看一下Bean注解的方法的处理过程

private static void dealBean(Object object,Class<?> klass) {
	Method[] methods = klass.getDeclaredMethods();
	for(Method method:methods) {
		//没有Bean注解的方法跳过
		if(!method.isAnnotationPresent(Bean.class)) {
			continue;
		}			
		
		if(method.getParameterCount() >0) {
			//TODO有参数的稍后再处理
			continue;
		}
		
		//处理无参数的bean注解
		Class<?> returnType = method.getReturnType();//获取返回值类型
		try {
			Object	beanObject = method.invoke(object);//通过执行方法获取返回值	
			//将方法的返回值类型及返回值装入beanPool
			BeanDefinition beanDefinition = new BeanDefinition();
			beanDefinition.setKlass(returnType);
			beanDefinition.setObject(beanObject);
			beanDefinition.setSingleton(true);
			beanDefinition.setInject(false);
			
			beanPool.put(returnType.getName(), beanDefinition);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		
	}
}

场景二
若相关类没有提供可用的构造方法;所谓的没有提供可用的构造方法包括相关构造方法是private的,或者,构造方法不能直接调用,或者,构造方法不能直接生成对象!在这种情况下,由于对于Component注解的处理是通过调用相关类的无参构造产生的,那么,对于上述情况,就不能产生这个类的对象!
此时,可以通过Bean注解,调用合适的获取该类对象的方法,取得这个类的对象,并加入BeanPool中!

下面以Calendar类为例,该类就是典型的构造方法是protected的,不能直接调用,需要使用getgetInstance()创建实例
在这里插入图片描述

public class Config {
	@Bean
	public Calendar getDate() {
		Calendar date = Calendar.getInstance();
		
		return date;
	}
}

场景三
相关类的对象,不是简单无参构造就能直接使用的;意思是:这个类虽然存在无参构造,但是,无参构造出来的对象不能直接使用。那么,在这种情况下,通过Bean注解的方法,完成其对象所必须的基础数据,从而使得该对象可用!

以数据库配置为例,connection对象就是一个很典型的,不能通过直接调用无参构造生成一个对象就可以正常使用的例子

@Component
public class Config {
	@Bean
	public Connection getConnection() {
		Connection connection = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			connection = DriverManager.getConnection(
					"jdbc:mysql://localhost:3306/test?useSSL=false", 
					"root",
					"123456");
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return connection;
	}
}

上述三种场景均为Autowired注解无法处理的,只能由Bean注解处理的情况。但是,Bean注解却不仅仅只能用于这三种场景,Autowired注解可以实现的功能Bean注解也同样可以,这意味着Bean注解也可以用在普通类上。

比如TwoClass一个普通类,将之放入Config类中,也能实现与Autowired相同的功能

@Component
public class Config {	
	@Bean
	public TwoClass getTwoClass() {
		TwoClass two = new TwoClass();
		return two;
	}
}

在上面列举了几种Bean注解的使用场景,而这些方法都只是无参的,但仍有一些有参的方法也需要Bean注解,关于有参数的方法处理会在之后的博文中说明。
全部代码请跳转–>GitHub https://github.com/Arrvine/mspring-IoC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值