反转:依赖对象的得到被反转,变为由本身建立,反转为从IOC容器中获取。
复制代码
1.代码更为简洁,不须要再去new须要的对象
2.面向接口编程,使用类和具体类解耦,易扩展,替换实现者
3.方便进行AOP加强(没有IOC就没法AOP)
复制代码
负责建立,管理类实例,向使用者提供实例
复制代码
IOC容器的工做:建立和管理Bean,它是一个工厂,负责对外提供Bean实例
复制代码
A:对外提供Bean实例,getBean()方法
复制代码
A:简单工厂模式中,当工厂能建立不少类产品,若是须要某类产品,须要告诉工厂
复制代码
A:各类类型的bean只能为Object<br><br>
复制代码
public interface BeanFactory { Object getBean(String name) throws Exception;}
复制代码
就是一个定义注册,咱们能够给它定义一个定义注册接口,让bean定义传入bean工厂,告知工厂建立何种类型的Bean
复制代码
public interface BeanDefinitionRegistry {}
复制代码
注册,获取bean定义
复制代码
每一个Bean要有一个独立的名称
复制代码
public interface BeanDefinitionRegistry {
/**
* 注册Bean
* @param beanName
* @param beanDefinition
* @throws Exception
*/
void registerBeanDefinition(String beanName,BeanDefinition beanDefinition) throws Exception;
/**
* 获取Bean
* @param beanName
* @return
*/
BeanDefinition getBeanDefinition(String beanName);
/**
* 判断Bean是否已经被注册
* @param beanName
* @return
*/
Boolean containsBeanDefinition(String beanName);
}
复制代码
告诉bean工厂该如何建立某类bean
复制代码
1.new 构造方法
2.工厂方法(静态,成员方法)
复制代码
1.new 构造方法(须要知道类名)
2.静态工厂方法(须要知道工厂类名,工厂方法名)
3.成员工厂方法(须要知道工厂类名--->工厂bean名,工厂方法名)
复制代码
否,由于有须要单例的状况
复制代码
1.获取bean的类名:getBeanClass()
2.获取工厂方法名:getFactoryMethodName()
3.获取工厂bean名:getFactoryBeanName()
4.是不是单例:getScope(){isSingleton(); isPrototype();}
复制代码
建立后可能须要的初始化
销毁时有可能出现的某些销毁逻辑(好比释放资源)
在bean定义提供让用户定制的初始化和销毁方法便可(getInitMethodName(),getDestroyMethodName())
复制代码
public interface BeanDefinition {
String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype";
Class<?> getBeanClass();
String getScope();
boolean isSingleton();
boolean isPrototype();
String getFactoryBeanName();
String getFactoryMethodName();
String getInitMethodName();
String getDestoryMethodName();
//tips:java8开始就能够直接写接口默认方法了
default boolean validate(){
//class没指定,工厂bean或工厂method不指定皆为不合法状况
if (this.getBeanClass()==null){
if(StringUtils.isBlank(getFactoryBeanName())||StringUtils.isBlank(getFactoryMethodName())){
return false;
}
}
//class和工厂bean同时存在
if (this.getBeanClass()!=null && StringUtils.isNotBlank(getFactoryBeanName())){
return false;
}
return true;
}
}
复制代码
import lombok.Data;
import org.apache.commons.lang.StringUtils;
@Data
public class GeneralBeanDefinition implements BeanDefinition{
private Class<?> beanClass;
private String scope = BeanDefinition.SCOPE_SINGLETON;
private String factoryBeanName;
private String factoryMethodName;
private String initMethodName;
private String destroyMethodName;
public void setScope(String scope) {
if (StringUtils.isNotBlank(scope)){
this.scope = scope;
}
}
@Override
public Class<?> getBeanClass() {
return this.beanClass;
}
@Override
public String getScope() {
return this.scope;
}
@Override
public boolean isSingleton() {
return BeanDefinition.SCOPE_SINGLETON.equals(this.scope);
}
@Override
public boolean isPrototype() {
return BeanDefinition.SCOPE_PROTOTYPE.equals(this.scope);
}
@Override
public String getFactoryBeanName() {
return factoryBeanName;
}
@Override
public String getFactoryMethodName() {
return factoryMethodName;
}
@Override
public String getInitMethodName() {
return this.initMethodName;
}
@Override
public String getDestoryMethodName() {
return this.destroyMethodName;
}
}
复制代码
A:Map
复制代码
A:直接设计为不能重名
复制代码
Map
复制代码
建立bean实例,进行初始化
复制代码
public class DefaultBeanFactory implements BeanFactory,BeanDefinitionRegistry, Closeable {
//common-logging包和log4j-api包配合便可
private final Log logger = LogFactory.getLog(getClass());
//考虑并发状况,256个前不须要进行扩容
private Map<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
private Map<String,Object> beanMap = new ConcurrentHashMap<>(256);
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws Exception {
//参数检查
Objects.requireNonNull(beanName,"注册bean须要输入beanName");
Objects.requireNonNull(beanDefinition,"注册bean须要输入beanDefinition");
//检验给入的bean是否合法
if (!beanDefinition.validate()){
throw new Exception("名字为["+beanName+"]的bean定义不合法,"+beanDefinition);
}
if (this.containsBeanDefinition(beanName)){
throw new Exception("名字为["+beanName+"]的bean定义已经存在,"+this.getBeanDefinition(beanName));
}
this.beanDefinitionMap.put(beanName,beanDefinition);
}
@Override
public BeanDefinition getBeanDefinition(String beanName) {
return this.beanDefinitionMap.get(beanName);
}
@Override
public Boolean containsBeanDefinition(String beanName) {
return this.beanDefinitionMap.containsKey(beanName);
}
@Override
public Object getBean(String name) throws Exception {
return this.doGetBean(name);
}
//不须要判断scope,由于只有单例bean才须要放入map中
//使用protected保证只有DefaultBeanFactory的子类能够调用该方法
protected Object doGetBean(String beanName) throws Exception{
Objects.requireNonNull(beanName,"beanName不能为空");
Object instance = beanMap.get(beanName);
if (instance != null){
return instance;
}
BeanDefinition beanDefinition = this.getBeanDefinition(beanName);
Objects.requireNonNull(beanDefinition,"beanDefinition不能为空");
Class<?> type = beanDefinition.getBeanClass();
//由于总共就只有3种方式,也不须要扩充或者是修改代码了,因此就不须要考虑使用策略模式了
if (type != null){
if (StringUtils.isBlank(beanDefinition.getFactoryMethodName())){
instance = this.createInstanceByConstructor(beanDefinition);
} else {
instance = this.createInstanceByStaticFactoryMethod(beanDefinition);
}
}else {
instance = this.createInstanceByFactoryBean(beanDefinition);
}
this.doInit(beanDefinition,instance);
if (beanDefinition.isSingleton()){
beanMap.put(beanName,instance);
}
return instance;
}
//构造方法来建立对象
private Object createInstanceByConstructor(BeanDefinition beanDefinition) throws IllegalAccessException, InstantiationException {
try{
return beanDefinition.getBeanClass().newInstance();
} catch (SecurityException e){
logger.error("建立bean的实例异常,beanDefinition"+beanDefinition,e);
throw e;
}
}
//静态工厂方法(暂时不考虑带参数)
private Object createInstanceByStaticFactoryMethod(BeanDefinition beanDefinition) throws Exception{
Class<?> type = beanDefinition.getBeanClass();
Method method = type.getMethod(beanDefinition.getFactoryMethodName(),null);
return method.invoke(type,null);
}
//工厂bean方法来建立对象(暂时不考虑带参数)
private Object createInstanceByFactoryBean(BeanDefinition beanDefinition) throws Exception{
Object factoryBean = this.doGetBean(beanDefinition.getFactoryBeanName());
Method method = factoryBean.getClass().getMethod(beanDefinition.getFactoryMethodName(),null);
return method.invoke(factoryBean,null);
}
//初始化方法
private void doInit(BeanDefinition beanDefinition, Object instance) throws Exception{
if (StringUtils.isNotBlank(beanDefinition.getInitMethodName())){
Method method = instance.getClass().getMethod(beanDefinition.getInitMethodName(),null);
method.invoke(instance,null);
}
}
@Override
public void close() throws IOException {
//执行单例实例的销毁方法
//遍历map把bean都取出来而后调用每一个bean的销毁方法
for (Map.Entry<String,BeanDefinition> entry : this.beanDefinitionMap.entrySet()){
String beanName = entry.getKey();
BeanDefinition beanDefinition = entry.getValue();
if (beanDefinition.isSingleton() && StringUtils.isNotBlank(beanDefinition.getDestoryMethodName())){
Object instance = this.beanMap.get(beanName);
try {
Method method = instance.getClass().getMethod(beanDefinition.getDestoryMethodName(),null);
method.invoke(instance,null);
}catch (NoSuchMethodException|SecurityException|IllegalAccessException|IllegalArgumentException|InvocationTargetException e){
logger.error("执行bean["+beanName+"] "+beanDefinition+"的销毁方法异常",e);
}
}
}
}
}
复制代码
A:能够提早实例化,空间换时间的方法,启动慢使用快并线程安全
复制代码
public class PreBuildBeanFactory extends DefaultBeanFactory{
private Log logger = LogFactory.getLog(getClass());
private List<String> beanNames = new ArrayList<>();
@Override
public void registerBeanDefinition(String beanName,BeanDefinition beanDefinition) throws Exception{
super.registerBeanDefinition(beanName,beanDefinition);
synchronized (beanNames){
beanNames.add(beanName);
}
}
//使用synchronized解决线程安全问题
public void preInstantiateSingletons() throws Exception{
synchronized (beanNames){
for (String name : beanNames){
BeanDefinition beanDefinition = this.getBeanDefinition(name);
if (beanDefinition.isSingleton()){
this.doGetBean(name);
if (logger.isDebugEnabled()){
logger.debug("preInstantiate:name="+name+" "+beanDefinition);
}
}
}
}
}
}
复制代码
public class Bean1 {
public void doSomething(){
System.out.println(System.currentTimeMillis()+" "+this);
}
public void init(){
System.out.println("bean1的init已执行");
}
public void destroy(){
System.out.println("bean1的destroy已执行");
}
}
复制代码
Bean1Factory.javajava
public class Bean1Factory {
public static Bean1 getBean1(){
return new Bean1();
}
public Bean1 getOtherBean1(){
return new Bean1();
}
}
复制代码
测试用例DefaultBeanFactoryTestapache
public class DefaultBeanFactoryTest {
static DefaultBeanFactory defaultBeanFactory = new DefaultBeanFactory();
@Test
public void testRegist() throws Exception{
GeneralBeanDefinition generalBeanDefinition = new GeneralBeanDefinition();
generalBeanDefinition.setBeanClass(Bean1.class);
generalBeanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
generalBeanDefinition.setInitMethodName("init");
generalBeanDefinition.setDestroyMethodName("destroy");
defaultBeanFactory.registerBeanDefinition("bean1",generalBeanDefinition);
}
@Test
public void testRegistStaticFactoryMethod() throws Exception{
GeneralBeanDefinition generalBeanDefinition = new GeneralBeanDefinition();
generalBeanDefinition.setBeanClass(Bean1Factory.class);
generalBeanDefinition.setFactoryMethodName("getBean1");
defaultBeanFactory.registerBeanDefinition("staticBean1",generalBeanDefinition);
}
@Test
public void testRegistFactoryMethod() throws Exception{
GeneralBeanDefinition generalBeanDefinition = new GeneralBeanDefinition();
generalBeanDefinition.setBeanClass(Bean1Factory.class);
String factoryBeanName = "factory";
defaultBeanFactory.registerBeanDefinition(factoryBeanName,generalBeanDefinition);
generalBeanDefinition = new GeneralBeanDefinition();
generalBeanDefinition.setFactoryBeanName(factoryBeanName);
generalBeanDefinition.setFactoryMethodName("getOtherBean1");
generalBeanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
defaultBeanFactory.registerBeanDefinition("factoryBean",generalBeanDefinition);
}
@AfterClass
public static void testGetBean() throws Exception{
System.out.println("构造方法方式···");
for (int i = 0;i<3;i++){
Bean1 bean1 = (Bean1) defaultBeanFactory.getBean("bean1");
bean1.doSomething();
}
System.out.println("静态工厂方法方式···");
for (int i = 0;i<3;i++){
Bean1 bean1 = (Bean1) defaultBeanFactory.getBean("staticBean1");
bean1.doSomething();
}
System.out.println("工厂方法方式···");
for (int i = 0;i<3;i++){
Bean1 bean1 = (Bean1) defaultBeanFactory.getBean("factoryBean");
bean1.doSomething();
}
defaultBeanFactory.close();
}
}
复制代码
构造方法方式···
bean1的init已执行
1555370012087 MySpring.Bean1@5e8c92f4
1555370012088 MySpring.Bean1@5e8c92f4
1555370012088 MySpring.Bean1@5e8c92f4
静态工厂方法方式···
1555370012088 MySpring.Bean1@50134894
1555370012088 MySpring.Bean1@50134894
1555370012088 MySpring.Bean1@50134894
工厂方法方式···
1555370012089 MySpring.Bean1@2957fcb0
1555370012089 MySpring.Bean1@1376c05c
1555370012090 MySpring.Bean1@51521cc1
bean1的destroy已执行复制代码