Spring 装配bean
一、实例化方式:
三种实例化方式:默认构造,静态工厂,实例工厂
1、默认构造(前面的文章都是最基本的默认构造)
配置语法:
<bean id="" class="">
2、静态工厂
配置语法:
<bean id="" class="工厂全限定类名" factory-method="静态方法">
咱们来举个栗子:
代码:
public class MyBeanFactory {
// 创建实例
public static UserService createService(){
return new UserServiceImpl();
}
}
配置:
<!--class 确定静态工厂全限定类名
factory-method 确定静态方法名-->
<bean id="userServiceId" class="[包名].MyBeanFactory" factory-method="createService"></bean>
3、实例工厂
public class MyBeanFactory {
public UserService createService(){
return new UserServiceImpl();
}
}
<!-- 创建工厂实例 -->
<bean id="myBeanFactoryId" class="com.itheima.c_inject.c_factory.MyBeanFactory"></bean>
<!-- 获得userservice
* factory-bean 确定工厂实例
* factory-method 确定普通方法
-->
<bean id="userServiceId" factory-bean="myBeanFactoryId" factory-method="createService"></bean>
二、作用域
配置信息:
<bean id="" class="" scope="">
<bean id="userServiceId" class="[包名].UserServiceImpl"
scope="prototype" ></bean>
如图所示为作用域类别与说明,Spring默认作用域为单例,常用的为单例(singleton)与多例(prototype)
三、生命周期
主要介绍初始化与销毁、后处理bean
1、初始化与销毁
目标方法执行前或后,将进行初始化或销毁。初始化方法常用于准备资源、初始化数据,销毁方法常用于释放资源等。
要求:1.容器必须close,销毁方法执行; 2.必须是单例的
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("e_lifecycle add user");
}
public void myInit(){
System.out.println("初始化");
}
public void myDestroy(){
System.out.println("销毁");
}
}
<bean id="userServiceId" class="com.itheima.e_lifecycle.UserServiceImpl"
init-method="myInit" destroy-method="myDestroy" ></bean>
2、BeanPostProcessor 后处理Bean
spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after() 。 配置
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("前方法 : " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
System.out.println("后方法 : " + beanName);
// bean 目标对象,可生成 jdk 代理
return Proxy.newProxyInstance(
MyBeanPostProcessor.class.getClassLoader(),
bean.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("------开启事务");
//执行目标方法
Object obj = method.invoke(bean, args);
System.out.println("------提交事务");
return obj;
}});
}
}
配置添加:
<!-- 将后处理的实现类注册给spring -->
<bean class="[包名].MyBeanPostProcessor"></bean>
四、属性依赖注入
依赖注入方式分为:手动装配和自动装配;
1、基于XML的手动装配:构造方法、setter方法;
1.1构造方法
目标类:
public class User {
private Integer uid;
private String username;
private Integer age;
public User(Integer uid, String username) {
super();
this.uid = uid;
this.username = username;
}
public User(String username, Integer age) {
super();
this.username = username;
this.age = age;
}
<!-- 构造方法注入
* <constructor-arg> 用于配置构造方法一个参数argument
name :参数的名称
value:设置普通数据
ref:引用数据,一般是另一个bean id值
index :参数的索引号,从0开始 。如果只有索引,匹配到了多个构造方法时,默认使用第一个。
type :确定参数类型
-->
<bean id="userId" class="com.itheima.f_xml.a_constructor.User" >
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
</bean>
1.2setter方法
<bean id="personId" class="com.itheima.f_xml.b_setter.Person">
<property name="pname" value="阳志"></property>
<property name="age">
<value>1234</value>
</property>
<property name="homeAddr" ref="homeAddrId"></property>
<property name="companyAddr">
<ref bean="companyAddrId"/>
</property>
</bean>
<bean id="homeAddrId" class="com.itheima.f_xml.b_setter.Address">
<property name="addr" value="阜南"></property>
<property name="tel" value="911"></property>
</bean>
<bean id="companyAddrId" class="com.itheima.f_xml.b_setter.Address">
<property name="addr" value="北京八宝山"></property>
<property name="tel" value="120"></property>
</bean>
1.3 P命令空间
对“setter方法注入”进行简化,替换
<bean p:属性名="普通值" p:属性名-ref="引用值">
p命名空间使用前提,必须添加命名空间
public class Person {
private String pname;
private Integer age;
private Address homeAddr;
private Address componyAddr;
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Address getHomeAddr() {
return homeAddr;
}
public void setHomeAddr(Address homeAddr) {
this.homeAddr = homeAddr;
}
public Address getComponyAddr() {
return componyAddr;
}
public void setComponyAddr(Address componyAddr) {
this.componyAddr = componyAddr;
}
@Override
public String toString() {
return "Person [pname=" + pname + ", age=" + age + ", homeAddr="
+ homeAddr + ", componyAddr=" + componyAddr + "]";
}
}
public class Address {
private String addr;
private String tel;
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Override
public String toString() {
return "Address [addr=" + addr + ", tel=" + tel + "]";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="person" class="com.jdwa.spring.f_xml.c_p.Person" p:pname="zkn" p:age="22"
p:componyAddr-ref="componyAddr" p:homeAddr-ref="homeAddr" />
<bean id="homeAddr" class="com.jdwa.spring.f_xml.c_p.Address"
p:addr="南京" p:tel="666"/>
<bean id="componyAddr" class="com.jdwa.spring.f_xml.c_p.Address"
p:addr="沈阳" p:tel="888"/>
</beans>
1.4.集合注入
public class CollData {
private String[] arrayData;
private List<String> listData;
private Set<String> setData;
private Map<String,String> mapData;
private Properties propsData;
public String[] getArrayData() {
return arrayData;
}
public void setArrayData(String[] arrayData) {
this.arrayData = arrayData;
}
public List<String> getListData() {
return listData;
}
public void setListData(List<String> listData) {
this.listData = listData;
}
public Set<String> getSetData() {
return setData;
}
public void setSetData(Set<String> setData) {
this.setData = setData;
}
public Map<String, String> getMapData() {
return mapData;
}
public void setMapData(Map<String, String> mapData) {
this.mapData = mapData;
}
public Properties getPropsData() {
return propsData;
}
public void setPropsData(Properties propsData) {
this.propsData = propsData;
}
@Override
public String toString() {
return "CollData [\narrayData=" + Arrays.toString(arrayData)
+ ", \nlistData=" + listData + ",\n setData=" + setData
+ ", \nmapData=" + mapData + ",\n propsData=" + propsData + "\n]";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="collData" class="com.jdwa.spring.f_xml.e_coll.CollData">
<property name="arrayData">
<array>
<value>array1</value>
<value>array2</value>
<value>array3</value>
</array>
</property>
<property name="listData">
<list>
<value>list1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
<property name="setData">
<set>
<value>set1</value>
<value>set2</value>
<value>set3</value>
</set>
</property>
<property name="mapData">
<map>
<entry key="map-key1" value="map-val1"></entry>
<entry key="map-key2" value="map-val2"></entry>
<entry key="map-key3" value="map-val3"></entry>
</map>
</property>
<property name="propsData">
<props>
<prop key="prop-key1">prop-val1</prop>
<prop key="prop-key2">prop-val2</prop>
<prop key="prop-key3">prop-val3</prop>
</props>
</property>
</bean>
</beans>
五、装配Bean 基于注解
- @Component取代
@Component("id") 取代
2.web开发,提供3个@Component注解衍生注解(功能一样)取代
@Repository :dao层
@Service:service层
@Controller:web层
3.依赖注入 ,给私有字段设置,也可以给setter方法设置
普通值:@Value("")
引用值:
方式1:按照【类型】注入
@Autowired
方式2:按照【名称】注入1
@Autowired
@Qualifier("名称")
方式3:按照【名称】注入2
@Resource("名称")
4.生命周期
初始化:@PostConstruct
销毁:@PreDestroy
5.作用域
@Scope("prototype") 多例
注解使用前提,添加命名空间,让spring扫描含有注解类
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
<context:component-scan base-package="【包名】"></context:component-scan>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="【包名】"></context:component-scan>
</beans>
大家有兴趣也可以关注我的公众号查看文章。