Spring学习Ⅱ
文章目录
Spring 初始化和销毁
jar包
工程目录
配置文件
applicationContext.xml
<?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">
<!--
init-method 用于配置初始化方法,准备数据等
destroy-method 用于配置销毁方法,清理资源等
-->
<bean id="userServiceId" class="UserServiceImpl"
init-method="myInit" destroy-method="myDestroy" ></bean>
</beans>
代码
public interface UserService {
void addUser();
}
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("addUser");
}
public void myInit(){
System.out.println("初始化");
}
public void myDestroy(){
System.out.println("销毁");
}
}
测试文件
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Execute {
@Test
public void demo02(){
//spring 工厂
String xmlPath = "resource/applicationContext.xml";
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
//要求:1.容器必须close,销毁方法执行; 2.必须是单例的
// applicationContext.getClass().getMethod("close").invoke(applicationContext);
// * 此方法接口中没有定义,实现类提供
applicationContext.close();
}
}
结果展示
Spring使用BeanPostProcessor接口进行代理
jar包
工程目录
配置文件
applicationContext.xml
<?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">
<!--
init-method 用于配置初始化方法,准备数据等
destroy-method 用于配置销毁方法,清理资源等
-->
<bean id="userServiceId" class="UserServiceImpl"
init-method="myInit" destroy-method="myDestroy" ></bean>
<!-- 将后处理的实现类注册给spring -->
<bean class="MyBeanPostProcessor"></bean>
</beans>
代码
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
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;
}});
}
}
public interface UserService {
void addUser();
}
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("addUser");
}
public void myInit(){
System.out.println("初始化");
}
public void myDestroy(){
System.out.println("销毁");
}
}
测试文件
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Execute {
@Test
public void demo02(){
//spring 工厂
String xmlPath = "resource/applicationContext.xml";
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
//要求:1.容器必须close,销毁方法执行; 2.必须是单例的
// applicationContext.getClass().getMethod("close").invoke(applicationContext);
// * 此方法接口中没有定义,实现类提供
applicationContext.close();
}
}
结果展示
备注
BeanPostProcessor接口的类会实现postProcessBeforeInitialization
和postProcessAfterInitialization
方法,这两种方法会在Spring配置文件中的init-method
方法调用前和调用后去执行。
在代码中执行完postProcessAfterInitialization
方法后,得到的实际是代理对象,最后调用addUser
是用代理对象调用的。
Spring依赖注入
构造函数依赖注入
配置文件
applicationContext.xml
<?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">
<!-- 构造方法注入
* <constructor-arg> 用于配置构造方法一个参数argument
name :参数的名称
value:设置普通数据
ref:引用数据,一般是另一个bean id值
index :参数的索引号,从0开始 。如果只有索引,匹配到了多个构造方法时,默认使用第一个。
type :确定参数类型
例如:使用名称name
<constructor-arg name="username" value="jack"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
例如2:【类型type 和 索引 index】
<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 id="userId" class="User" >
<constructor-arg name="uid" value="1233"></constructor-arg>
<constructor-arg name="username" value="jack"></constructor-arg>
<constructor-arg name="age" value="18"></constructor-arg>
</bean>
</beans>
代码
public class User {
private Integer uid;
private String username;
private Integer age;
public User(Integer uid, String username, Integer age) {
this.uid = uid;
this.username = username;
this.age = age;
}
@Override
public String toString() {
return "User{" +
"uid=" + uid +
", username='" + username + '\'' +
", age=" + age +
'}';
}
}
测试
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Execute {
@Test
public void demo02(){
String xmlPath = "resource/applicationContext.xml";
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
User user = (User) applicationContext.getBean("userId");
System.out.println("user = " + user);
}
}
结果
setter方法
配置文件
applicationContext.xml
<?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">
<!-- setter方法注入
* 普通数据
<property name="" value="值">
等效
<property name="">
<value>值
* 引用数据
<property name="" ref="另一个bean">
等效
<property name="">
<ref bean="另一个bean"/>
-->
<bean id="personId" class="Person">
<property name="pname" value="耀眼"></property>
<property name="age">
<value>24</value>
</property>
<property name="homeAddr" ref="homeAddrId"></property>
<property name="companyAddr">
<ref bean="companyAddrId"/>
</property>
</bean>
<bean id="homeAddrId" class="Address">
<property name="addr" value="阜南"></property>
<property name="tel" value="456"></property>
</bean>
<bean id="companyAddrId" class="Address">
<property name="addr" value="沈阳"></property>
<property name="tel" value="123"></property>
</bean>
</beans>
代码
public class Person {
private String pname;
private Integer age;
private Address homeAddr; //家庭地址
private Address companyAddr; //公司地址
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 getCompanyAddr() {
return companyAddr;
}
public void setCompanyAddr(Address companyAddr) {
this.companyAddr = companyAddr;
}
@Override
public String toString() {
return "Person [pname=" + pname + ", age=" + age + ", homeAddr=" + homeAddr + ", companyAddr=" + companyAddr + "]";
}
}
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 + "]";
}
}
测试文件
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Execute {
@Test
public void demo02(){
//从spring容器获得
String xmlPath = "resource/applicationContext.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
Person person = (Person) applicationContext.getBean("personId");
System.out.println(person);
}
}
结果
集合注入
配置文件
applicationContext.xml
<?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">
<!--
集合的注入都是给<property>添加子标签
数组:<array>
List:<list>
Set:<set>
Map:<map> ,map存放k/v 键值对,使用<entry>描述
Properties:<props> <prop key=""></prop> 【】
普通数据:<value>
引用数据:<ref>
-->
<bean id="collDataId" class="CollData" >
<property name="arrayData">
<array>
<value>DS</value>
<value>DZD</value>
<value>屌丝</value>
<value>屌中屌</value>
</array>
</property>
<property name="listData">
<list>
<value>于嵩楠</value>
<value>曾卫</value>
<value>杨煜</value>
<value>曾小贤</value>
</list>
</property>
<property name="setData">
<set>
<value>停封</value>
<value>薄纸</value>
<value>关系</value>
</set>
</property>
<property name="mapData">
<map>
<entry key="jack" value="杰克"></entry>
<entry>
<key><value>rose</value></key>
<value>肉丝</value>
</entry>
</map>
</property>
<property name="propsData">
<props>
<prop key="高富帅">嫐</prop>
<prop key="白富美">嬲</prop>
<prop key="男屌丝">挊</prop>
</props>
</property>
</bean>
</beans>
代码
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
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 + ", \nsetData=" + setData + ", \nmapData=" + mapData + ", \npropsData=" + propsData + "\n]";
}
}
测试文件
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Execute {
@Test
public void demo02(){
//spring 工厂
String xmlPath = "resources/applicationContext.xml";
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
CollData collData = (CollData) applicationContext.getBean("collDataId");
System.out.println(collData);
}
}