美文网首页js css html
[java]42、Spring-02

[java]42、Spring-02

作者: 史记_d5da | 来源:发表于2022-05-15 16:22 被阅读0次

1、Converter

1、Spring已经内置了基本的类型转换功能,比如
StringintStringDate(支持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-contextmysql-connector-javamybatis
可选:logback-classicdruid
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>

数据源也可以使用
SpringDriverManagerDataSource

<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>

MyBatisPooledDataSource

<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的代理对象,beaniddao类名的小驼峰形式
比如:com.sj.dao.SkillDaoidskillDao
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)、CGLibCode 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;
        }
    }
}

相关文章

网友评论

    本文标题:[java]42、Spring-02

    本文链接:https://www.haomeiwen.com/subject/pvrcurtx.html