1、属性注入
2、构造器注入
userinfo.properties
命名空间后,等价于 ->
userinfo.properties
使用bean的parent属性指定继承哪个bean的配置。
使用bean的scope属性来配置bean的作用域。
bean中属性有init-method初始化方法和destroy-method销毁方法
自定义一个类实现 BeanPostProcessor接口,并具体提供postProcessBeforeInitialzation(Object bean,String beanName)和postProcessAfterInitialization(Object bean,String beanName)方法,其中postProcessBeforeInitialzation是在init-method之前被调用而postProcessAfterInitialization是在init-method之后被调用。参数中bean是bean的实例本身,beanName是IOC容器配置的bean的名字,返回值是实际上返回给用户的那个Bean,可以在以上两个方法中修改返回的bean,甚至返回一个新的Bean。
在配置文件中添加后置处理器的配置
实现BeanPostProcessor接口(处理所有的bean)
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("处理后期:" + bean);
return bean;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("处理前期:" + bean);
return bean;
}
}
通过静态工厂方法来配置Bean,不是配置静态工厂方法实例,而是配置bean实例。class属性指向静态工厂方法的全类名,factory-method指向静态工厂方法的名字,constructor-arg如果工厂方法需要传入参数,则使用constructor-arg来配置参数。
配置xml文件
静态工厂类
public class StaticFactory {
private static Map map = new HashMap();
static {
map.put("奔驰", new Car("奔驰", 300000));
map.put("奥迪", new Car("奥迪", 300000));
}
public static Car getCar(String name) {
return map.get(name);
}
}
配置xml文件
工厂方法
public class IntertanceFactory {
private Map map = null;
public IntertanceFactory() {
map = new HashMap();
map.put("奔驰", new Car("奔驰", 300000));
map.put("奥迪", new Car("奥迪", 300000));
}
public Car getCar(String name) {
return map.get(name);
}
}
实现FactoryBean接口,实际返回的实例是getObject()方法返回的实例。
配置xml文件
实现FactoryBean接口
public class CarFactoryBean implements FactoryBean {
private String name = null;
public void setName(String name) {
this.name = name;
}
@Override
public Car getObject() throws Exception {
return new Car(name, 50000);
}
@Override
public Class> getObjectType() {
return Car.class;
}
@Override
public boolean isSingleton() {
return true;
}
}
Spring能够从classpath下自动扫描、侦测和实例化具有特定注解的组件。
特定组件包括:
对于扫描到的组件,Spring有默认的命名策略,使用非限定类名第一个字母小写,也可以在注解中通过value属性值标识组件的名称。
两个子节点中type类型:annotation:注解类型,assignable:指定类型
默认情况下,@autowired是按类型注入的,所有使用@Aurowired注解的属性都需要被设置,当Spring找不到匹配的Bean装配属性时,会抛出异常。若某一属性允许不被设置,可以设置@Autowired注解的required属性为false。当IOC容器里存在多个类型兼容的Bean时,通常类型的自动装配将无法工作,此时可以在@Qualifier注解里提供Bean的名称,Spring允许对方法的入参标注@Qualifier已指定注入Bean的名称。
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
@Resource装配顺序
1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
//////////////////////////////////////////////////////////////////////////
package com.my.spring.bean.generic;
public class BaseRepository {
}
//////////////////////////////////////////////////////////////////////////
package com.my.spring.bean.generic;
import org.springframework.beans.factory.annotation.Autowired;
public class BaseService {
@Autowired
private BaseRepository baseRepository;
public void getService() {
System.out.println("BaseService...");
System.out.println(baseRepository);
}
}
//////////////////////////////////////////////////////////////////////////////
package com.my.spring.bean.generic;
import org.springframework.stereotype.Service;
@Service
public class UserService extends BaseService {
}
//////////////////////////////////////////////////////////////////////////////
package com.my.spring.bean.generic;
import org.springframework.stereotype.Repository;
@Repository
public class UserRepository extends BaseRepository {
}