spring总结
2009-2-19 向先函 制作
2009-2-23 完成
一、一般方式
UserManager userManager = new UserManagerImpl(new UserDao4MySqlImpl());
二、注入方法
构造注入时机比较早
Manager中
private UserDao userDao;
// public UserManagerImpl(UserDao userDao) {
// this.userDao = userDao;
// }
Ioc容器中
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="userDao4MySqlImpl" class="com.bjsxt.spring.dao.UserDao4MySqlImpl"/>
<bean id="userManager" class="com.bjsxt.spring.manager.UserManagerImpl">
<!-- 构造方法注入
<constructor-arg ref="userDao4OracleImpl"/>
</bean>
调用类中
//获取配置文件
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
//获取指定的类
UserManager userManager = (UserManager)factory.getBean("userManager");
userManager.save("张三", "123");
set注入
manager中
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
Ioc容器中
<bean id="userManager" class="com.bjsxt.spring.manager.UserManagerImpl">
<property name="userDao" ref="userDao4OracleImpl"/>
</bean>
四、属性注入
注意log4j里面的路径可以查看运行日志
log4j.appender.logfile.File=${petstore.root}/WEB-INF/petstore.log
属性
private String strValue;
private int intValue;
private List listValue;
private Set setValue;
private String[] arrayValue;
private Map mapValue;
注入配置
<bean id="bean1" class="com.bjsxt.spring.Bean1">
<property name="strValue" value="Hello"/>
<!--
<property name="intValue" value="123"/>
-->
<property name="intValue">
<value>123</value>
</property>
<property name="listValue">
<list>
<value>list1</value>
<value>list2</value>
</list>
</property>
<property name="setValue">
<set>
<value>set1</value>
<value>set2</value>
</set>
</property>
<property name="arrayValue">
<list>
<value>array1</value>
<value>array2</value>
</list>
</property>
<property name="mapValue">
<map>
<entry key="k1" value="v1"/>
<entry key="k2" value="v2"/>
</map>
</property>
单元测试类要引用junit.jar
继承InjectionTest extends TestCase
testInjection1()
注意命名规则
调用:
public class InjectionTest extends TestCase {
private BeanFactory factory;
//用于初始化方法
@Override
protected void setUp() throws Exception {
factory = new ClassPathXmlApplicationContext("applicationContext-*.xml");
}
public void testInjection1() {
Bean1 bean1 = (Bean1)factory.getBean("bean1");
System.out.println("bean1.strValue=" + bean1.getStrValue());
System.out.println("bean1.intValue=" + bean1.getIntValue());
System.out.println("bean1.listValue=" + bean1.getListValue());
System.out.println("bean1.setValue=" + bean1.getSetValue());
System.out.println("bean1.arrayValue=" + bean1.getArrayValue());
System.out.println("bean1.mapValue=" + bean1.getMapValue());
}
五、自定义属性编辑器
日期注入
属性
private Date dateValue;
写一个属性编辑器(类)
* 继承PropertyEditorSupport类,覆写setAsText()方法,参见:UtilDatePropertyEditor.java
/**
* java.util.Date属性编辑器
* @author Administrator
*
*/
public class UtilDatePropertyEditor extends PropertyEditorSupport {
private String format="yyyy-MM-dd";
@Override
public void setAsText(String text) throws IllegalArgumentException {
System.out.println("UtilDatePropertyEditor.saveAsText() -- text=" + text);
SimpleDateFormat sdf = new SimpleDateFormat(format);
try {
Date d = sdf.parse(text);
this.setValue(d);
} catch (ParseException e) {
e.printStackTrace();
}
}
//注入对象
public void setFormat(String format) {
this.format = format;
}
注册编辑器
<!-- 定义属性编辑器 -->
<bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<!-- 内部bean 和格式调用的时候改格式就可以了-->
<bean class="com.bjsxt.spring.UtilDatePropertyEditor">
<property name="format" value="yyyy-MM-dd"/>
</bean>
</entry>
</map>
</property>
</bean>
<!-- 一般方法 -->
<!--
<bean id="utilDatePropertyEditor" class="com.bjsxt.spring.UtilDatePropertyEditor"></bean>
-->
配置
<property name="dateValue">
<value>2008-08-15</value>
</property>
调用
System.out.println("bean1.dateValue=" + bean1.getDateValue());
六,公共属性的注入
<bean id="bean2" class="com.bjsxt.spring.Bean2">
<property name="bean3" ref="bean3"/>
<property name="bean4">
<ref bean="bean4"/>
</property>
<property name="bean5" ref="bean5"/>
</bean>
改进前//-------------------------------------------------------------------------------------------------
<!-- 抽出下面的方法 -->
<!--
<bean id="bean3" class="com.bjsxt.spring.Bean3">
<property name="id" value="1000"/>
<property name="name">
<value>Jack</value>
</property>
<property name="password" value="123"/>
</bean>
<bean id="bean4" class="com.bjsxt.spring.Bean4">
<property name="id" value="1000"/>
<property name="name" value="Jack"/>
</bean>
-->
改进后
//抽取类抽象类
<bean id="beanAbstract" abstract="true">
<property name="id" value="1000"/>
<property name="name" value="Jack"/>
</bean>
<bean id="bean3" class="com.bjsxt.spring.Bean3" parent="beanAbstract">
//复写name
<property name="name" value="Tom"/>
//补写password
<property name="password" value="123"/>
</bean>
<bean id="bean4" class="com.bjsxt.spring.Bean4" parent="beanAbstract"/>
//-------------------------------------------------
<bean id="bean5" class="com.bjsxt.spring.Bean5">
<property name="age" value="20"/>
</bean>
补充说明
依赖对象的注入方式,可以采用:
* ref属性
* <ref>标签
* 内部<bean>来定义
如何将公共的注入定义描述出来?
* 通过<bean>标签定义公共的属性,指定abstract=true
* 具有相同属性的类在<bean>标签中指定其parent属性
七、bean的作用域
<!-- 默认是singleton,但实例,改成prototype就是原型啦
<bean id="bean1" class="com.bjsxt.spring.Bean1" scope="singleton"/>
-->
<bean id="bean1" class="com.bjsxt.spring.Bean1" scope="prototype"/>
scope可以取值:
* singleton:每次调用getBean的时候返回相同的实例
* prototype:每次调用getBean的时候返回不同的实例
八、自动装配//快速开发阶段可以用,一般不建议使用
更具名称装配
写了bean2.3.4.5
在配置文件中
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
default-autowire="byName"//只对当前文件生效
>
<!--
<bean id="bean2" class="com.bjsxt.spring.Bean2">
<property name="bean3" ref="bean3"/>
<property name="bean4">
<ref bean="bean4"/>
</property>
<property name="bean5" ref="bean5"/>
</bean>
-->
根据名称装配代替上面面
<bean id="bean2" class="com.bjsxt.spring.Bean2"/>
<bean id="bean5" class="com.bjsxt.spring.Bean5">
<property name="age" value="20"/>
</bean>
根据类型自动装配//只于类型有关
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"
default-autowire="byType"
>
<bean id="bean2" class="com.bjsxt.spring.Bean2"/>
<bean id="bean5111" class="com.bjsxt.spring.Bean5">
<property name="age" value="20"/>
注入类
private Bean3 bean3;
private Bean4 bean4;
private Bean5 bean5;
八、代理模式// 试读而已
安全性检查的一般方法,使用静态代理
//实现类,需要检查安全性
public class UserManagerImpl implements UserManager {
public void addUser(String username, String password) {
System.out.println("-------UserManagerImpl.addUser()----------");
}
public void deleteUser(int id) {
System.out.println("-------UserManagerImpl.deleteUser()----------");
}
public String findUserById(int id) {
System.out.println("-------UserManagerImpl.findUserById()----------");
return null;
}
public void modifyUser(int id, String username, String password) {
System.out.println("-------UserManagerImpl.modifyUser()----------");
}
}
//建立安全性检查类实现接口
public class UserManagerImplProxy implements UserManager {
private UserManager userManager;
public UserManagerImplProxy(UserManager userManager) {
this.userManager = userManager;
}
public void addUser(String username, String password) {
checkSecurity();
this.userManager.addUser(username, password);
}
public void deleteUser(int id) {
checkSecurity();
//用接口调用
this.userManager.deleteUser(id);
}
public String findUserById(int id) {
return null;
}
public void modifyUser(int id, String username, String password) {
}
//检查安全性
private void checkSecurity() {
System.out.println("----------checkSecurity()---------------");
}
//客户端调用
UserManager userManager = new UserManagerImplProxy(new UserManagerImpl());
//userManager.addUser("张三", "123");
userManager.deleteUser(1);
九、jdk动态代理
/**
* 建立安全性检查处理类
* @author Administrator
*
*/
public class SecurityHandler implements InvocationHandler {
private Object targetObject;
public Object newProxy(Object targetObject) {
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
this);
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//可以用method判断是什么方法用调用安全性检查
checkSecurity();
//返回值,可以不拦截异常
Object ret = null;
try {
//调用目标对象上的方法,传递方法和参数
ret = method.invoke(this.targetObject, args);
}catch(Exception e) {
e.printStackTrace();
throw new java.lang.RuntimeException(e);
}
return ret;
}
private void checkSecurity() {
System.out.println("----------checkSecurity()---------------");