Spring中bean的理解

实例化bean:

  • 无参构造器
<bean id="Bean1" class="bean.Bean1"></bean>
  • 静态工厂
public class Bean2{ 
private Bean1(){} 
public static Bean1 getInstance(){
 return new Bean1(); 
    } 
} 
<bean id="bean2" class="bean.Bean2" factory-method="getInstance"> <bean>
  • 实例工厂:
public class Bean3{
    //封装
}
public class Bean3Facroty{
    //封装
    public Bean3 createBean(){
        return new Bean3();
    }
}
<bean id="bean3Facroty" class="bean.Bean3Facroty" > <bean>
<bean id="bean3" class="bean.Bean3" factory-bean="bean3Facroty" factory-method="createBean"> <bean>
  • 实现FactoryBean接口
public class Bean4 {
    //类本身的封装
}
public class Bean4FactoryBean implements FactoryBean<Bean4x{
@Override
public Bean4 getobject() throws Exception {//编写一些额外的功能
    return new Bean4();
}
@Override
public Class?> getObjectType() {
	// TODO Auto-generated method stub
	return null;
}
@Override
public boolean issingleton() {
	// TODO Auto-generated method stub
	return false;
     }
 }
 <bean id="bean4" class="bean.Bean4FactoryBean"> <bean>

获取bean:

UserDao :
    package dao.iface;
    public interface UserDao {
        //空的,仅仅测试
    }
UserDaoImpl :
    package dao.impl;
    public class UserDaoImpl implements UserDao {
        //空的,仅仅测试
    }

根据id/name获取:byName(就是通过Bean的id或者name)

applicationContext.xml:
    <bean id="userDao" class="dao.impl.UserDaoImpl"> </bean>
    
UserDao userDao = (UserDao) applicationContext.getBean("userDao");

根据class类型获取:byType(就是按Bean的Class的类型)

applicationContext.xml:
    <bean id="userDao" class="dao.impl.UserDaoImpl"> </bean>
UserDao userDao = applicationContext.getBean(UserDaoImpl.class);

XML中bean的注入:

  • 构造器注入(必须提供一个无参构造器)
Class Car{  
    private String name;  
    private String CarNo;  
    private Double price 
    public car(){}//必须提供一个无参构造器
    public Car(String name,String CarNo,Double price){  
        this.name = name;  
        this.CarNo= CarNo;  
        this.price=price;  
    }  
    //setter、getter...  
}  
//传入参数类型无重复时候可以使用type
<bean id="car" class="com.Car">
   <constructor-arg type="java.lang.String" value="hongqi"/>  
    <constructor-arg type="java.lang.Double" value="555555">  
</bean>
//ref注入对象类型值
//传入参数类型重复时候使用index
<bean id="car" class="com.Car">
   <constructor-arg index="0" value="hongqi"/>  
    <constructor-arg index="1" value="苏A00000">  
    <constructor-arg index="2" value="555555">  
</bean>
  • setter注入
Class Car{
    private Integer iDCard;  
    public void setIDCard(Integer iDCard){  
        this.iDCard=iDCard;  
    }  
}  
<bean id="car" class="com.Car">  
    <property name="IDCard">
        <value>123</value>
    </property>  
</bean>

注解注入:

  • 简单类型注入
@Component("user")
public class User {
    //@Value注解可以放在属性上,通过反射实现,不是通过构造器或者set方法
    @Value("10")
    private int uid;
    @Value("admin")
    private String uname;
    private String password;
    //属性的set方法上,通过set方法注入
    @Value("123456")
    public void setPassword(String password){
        this.password=password;
        }
    }
  • 复杂属性注入
@Component("userDao")
public class UserDaoImpl(){}
//@Value和spEL结合(使用较少)
@Value ("#{userDao}")
private UserDao userDao; SpEL表达式
public void setUserDao(UserDao userDao){
	this.userDao = userDao;
 }

@Resource

byName的自动装配是跟类中的属性有关,其实不是,使用byName进行自动装配时,是利用Java的反射机制获取自动装配类中的set方法名,去掉set后将其首字母小写再到IOC容器中查找是否有对应的beanId,如果有则查看该bean的类型与set方法的参数类型是否匹配,匹配上了则调用set方法进行依赖注入。因此,byName的自动装配跟set方法名和参数类型有关,跟属性名无关。

默认按照byName方式进行装配,byName无法装配则使用byType,属于J2EE自带注解,没有指定name时,name指的是变量名

  • 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
  • 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
  • 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
  • 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;

@Autowired

使用byType进行自动装配时,是利用Java的反射机制获取测试类中的set方法的参数类型,寻找此接口类型的实现类或子类,找到后将其首字母小写与IOC容器中的beanId进行匹配,匹配成功后则调用set方法进行依赖注入。因此,byType自动装配与方法名无关,与属性名无关,与set方法的参数类型有关。

默认按byType自动注入,byType无法装配则使用byName,是Spring的注解

  • @Autowired默认按类型装配(属于spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false;
  • @Autowired按类型装配的过程中,如果发现找到多个bean,则又按照byName方式进行比对,如果还有多个,则报出异常;可以通过设置@Autowired + @ Qualifier("byName") 表示按照名称注入
@Resource
private HelloWorld helloWorld;
Java的反射机制会自动的帮我们生成一个名为setHelloWorld的方法,进行byName,如果不匹配就byType

bean的作用域:

  1. singleton:当一个bean的作用域为singleton,那么Spring IoC容器中只会存在一个共享的bean实例
  2. prototype:prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例
  3. request:当一个bean的作用域为request,表示在一次HTTP请求中,一个bean定义对应一个实例
  4. session:当一个bean的作用域为session,表示在一个HTTP Session中,一个bean定义对应一个实例
  5. globalSession:当一个bean的作用域为globalSession,表示在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。

bean的生命周期:

简单的理解就是:

  • 实例化 Instantiation
  • 属性赋值 Populate
  • 初始化 Initialization
  • 销毁 Destruction

实现接口BeanPostProcessor(后处理bean)

https://www.cnblogs.com/javazhiyin/p/10905294.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值