1、Converter
1、Spring
已经内置了基本的类型转换功能,比如
String
转int
、String
转 Date
(支持yyyy/MM/dd
格式)
<bean id="person" class="com.sj.domain.Person" p:birthday="2011/09/08" />
2、自定义Converter
实现Converter
接口
public class DateConverter implements Converter<String, Date> {
private String format;
public void setFormat(String format) {
this.format = format;
}
@Override
public Date convert(String s) {
SimpleDateFormat fmt = new SimpleDateFormat(format);
try {
return fmt.parse(s);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
注册Converter
<bean id="person" class="com.sj.domain.Person" p:birthday="2011-09-08" />
<bean id="dateConverter" class="com.sj.domain.DateConverter" p:format="yyyy-MM-dd" />
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="dateConverter" />
</set>
</property>
</bean>
2、Spring&MyBatis
1、在pom.xml
中添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.5</version>
</dependency>
其他依赖
必须:spring-context
、mysql-connector-java
、mybatis
可选:logback-classic
、druid
2、在applicationContext.xml
添加
数据源
<context:property-placeholder location="db.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
数据源也可以使用
Spring
的DriverManagerDataSource
<bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
<property name="driver" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
MyBatis
的PooledDataSource
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
添加SqlSessionFactoryBean
<!-- 创建SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 这个包底下的类会自动设置别名(一般是领域模型) -->
<property name="typeAliasesPackage" value="com.mj.domain"/>
<!-- 映射文件的位置 -->
<property name="mapperLocations">
<array>
<value>mappers/*.xml</value>
</array>
</property>
</bean>
添加MapperScannerConfigurer
<!-- 扫描dao -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 设置SqlSessionFactoryBean的id -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 设置dao的包 -->
<property name="basePackage" value="com.mj.dao"/>
</bean>
配置完成后可以通过getBean
方法获取dao
的代理对象,bean
的id
是dao
类名的小驼峰形式
比如:com.sj.dao.SkillDao
的id
是skillDao
3、测试代码
public void list() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
SkillDao skillDao = ctx.getBean("skillDao", SkillDao.class);
List<Skill> skills = skillDao.list();
System.out.println(skills);
}
3、bean的生命周期
1、bean
的生命周期
applicationContext.xml
的初始化bean
文件
-
scope="singleton"
,bean
的生命周期和容器绑定 -
scope="prototype"
,每调用一次bean
会生成一个对象,最终根据系统的垃圾回收机制决定容器和bean
销毁
<bean id="userService" class="com.sj.service.impl.UserServiceImpl"
p:age="20"
init-method="init"
destroy-method="dealloc" scope="singleton"/>
<bean class="com.sj.processor.MyProcesser" />
java
呈现的生命周期代码
public class MyProcesser implements BeanPostProcessor {
// 05-在bean开始处理前调用的方法 - BeanPostProcessor
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}
// 08-在bean处理后调用的方法- BeanPostProcessor
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}
public class UserServiceImpl implements
BeanNameAware,
ApplicationContextAware,
InitializingBean,
DisposableBean, UserService {
private Integer age;
// 02-Set方法
public void setAge(Integer age) {this.age = age;}
// 01-初始化构造方法
public UserServiceImpl() {}
// 09-业务调用
@Override
public boolean login(String username, String password) {}
// 07-初始化方法
public void init() {}
// 11-容器销毁方法
public void dealloc() {}
// 03-在set方法完毕之后进行的处理-BeanNameAware
@Override
public void setBeanName(String name) {}
// 04-容器回调方法-ApplicationContextAware
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {}
// 10-bean销毁方法-DisposableBean
@Override
public void destroy() throws Exception {}
// 06-InitializingBean在初始化方法之前调用的方法
@Override
public void afterPropertiesSet() throws Exception {}
}
2、代理
目标:在不修改目标类的目标方法代码的前提下,为目标方法增加额外功能
代理类中国必须也有同样的目标方法
1)、代理类实现跟目标类同样的接口
2)、若目标类没有实现接口,代理类继承目标类
静态代理
开发任意手动编写代理类(创建对应的*.java
文件)
基本上,一个目标类就要编写一个代理类
例如applicationContext.xml
中添加
<bean id="userService" class="com.sj.proxy.UserServiceProxy" >
<property name="target">
<bean id="target" class="com.sj.service.impl.UserServiceImpl" />
</property>
</bean>
代理类UserServiceProxy
中可以添加日志,增强业务,目标类中UserServiceImpl
实现原有的业务。
public class UserServiceProxy implements UserService {
private UserService target;
public void setTarget(UserService target) {
this.target = target;
}
@Override
public boolean login(String username, String password) {
System.out.println("日志---------------------1");
boolean result = target.login(username, password);
System.out.println("日志---------------------2");
return result;
}
}
动态代理:在程序运行过程中动态生成字节码文件
动态代理常见的有两种实现方案:
1)、JDK
自带的
public class LogProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Object proxyObject = Proxy.newProxyInstance(
getClass().getClassLoader(), // 类加载器
bean.getClass().getInterfaces(), // 代理类需要实现的接口
new LogInvocationHandler(bean));
return proxyObject;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
public static class LogInvocationHandler implements InvocationHandler {
public final Object target;
public LogInvocationHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// proxy 代理类,
// method 目标方法
// args 目标方法的参数
System.out.println("proxy -- 1");
Object result = method.invoke(target, args);
System.out.println("proxy -- 2");
return result;
}
}
}
2)、CGLib
(Code Generation Library
)
public class LogProcessor2 implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Enhancer enhancer = new Enhancer();
enhancer.setClassLoader(getClass().getClassLoader());
enhancer.setCallback(new LogMethodInterceptor(bean));
enhancer.setSuperclass(bean.getClass());
return enhancer.create();
}
private static class LogMethodInterceptor implements MethodInterceptor {
public final Object target;
public LogMethodInterceptor(Object target) {
this.target = target;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("proxy -- 1");
Object result = method.invoke(target, objects);
System.out.println("proxy -- 2");
return result;
}
}
}
网友评论