SSH-Spring学习随笔

IOC基础使用
1、利用xml方式进行Bean管理
<?xml version="1.0" encoding="UTF-8"?>
<beans default-lazy-init="true"
    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:标识做用,不能含有特殊符号 
        name:遗留属性,几乎不用,与id相似,可使用'/'特殊符号
        class:映射的class的全路径 
        scope:该Bean的做用范围 
            singleton:默认值,单表该Bean为一个单实例对象,即每次使用的都是同一个Bean,与Servlet同样 
            prototype:标识该Bean为一个多实例对象,与Action同样 
            request:spring建立一个Bean示例对象后存入request域对象中 
            session:spring建立一个Bean示例对象后存入session域对象中 
            globalSession:应用在Porlet环境中,若是没有Porlet环境,那么至关与Session 
        init-method:Bean示例初始化时执行该方法 
        destroy-method:Bean实例销毁时执行该方法,若是想执行该方法,必须是单实例对象,并且只有在ApplicationContext(工厂)关闭时才会执行 
        lazy-init:只对单例对象有用,是否延迟建立对象 默认值为default,即false,在加载配置文件时即建立实例对象 
            true:在加载配置文件时延迟建立实例对象,调用applicationContext.getBean()方法时建立实例对象 
            在beans标签中配置default-lazy-init="true",即将lazy-init的默认值设为对应的true or false ,控制全部的bean -->
 
    <!-- 利用静态工厂建立Bean对象示例 -->
    <bean id="beanFactory" factory-method="getCustomer"
        class="cn.zz.spring.factory.BeanFactory"></bean>
 
    <!-- 利用实例工厂建立Bean对象示例 
        1.先建立示例工厂对象 
        2.经过示例工厂中对应方法建立Bean示例对象 
    -->
    <bean id="beanFactory2" class="cn.zz.spring.factory.BeanFactory2"></bean>
    <bean id="customer" factory-bean="beanFactory2" factory-method="getCustomer"></bean>
 
    <!-- 利用无参构造建立Bean实例对象 -->
    <bean id="user" class="cn.zz.spring.domain.User" scope="singleton"
        init-method="init" destroy-method="destroy" lazy-init="false">
        <!-- 利用set方法注入String类型属性 -->
        <property name="string" value="str"></property>
        <!-- 利用set方法注入List集合类型属性 -->
        <property name="list">
            <list>
                <value>123</value>
                <value>456</value>
                <value>789</value>
                <value>123</value>
                <value>456</value>
            </list>
        </property>
        <!-- 利用set方法注入int类型属性 -->
        <property name="i" value="1"></property>
        <!-- 利用set方法注入double类型属性 -->
        <property name="d" value="10.05"></property>
        <!-- 利用set方法注入boolean类型属性 -->
        <property name="b" value="1"></property>
        <!-- 利用set方法注入数组类型属性 -->
        <property name="arrs">
            <array>
                <value>111</value>
                <value>222</value>
                <value>333</value>
                <value>444</value>
                <!-- <ref bean="xxx"/> -->
            </array>
        </property>
        <!-- 利用set方法注入Properties类型属性 -->
        <property name="properties">
            <props>
                <prop key="name">123</prop>
                <prop key="word">456</prop>
                <prop key="age">789</prop>
            </props>
        </property>
        <!-- 利用set方法注入Map集合类型属性 -->
        <property name="map">
            <map>
                <entry key="a" value="123"></entry>
                <entry key="b" value="456"></entry>
                <entry key="c" value="789"></entry>
                <!-- <entry key-ref="xxx" value-ref="xxx"></entry> -->
            </map>
        </property>
    </bean>
 
    <!-- 利用无参构造建立实例对象 -->
    <bean name="people" class="cn.zz.spring.domain.People">
        <!-- 利用set方法注入集合类型属性 -->
        <property name="userlist">
            <list>
                <!-- 注入object类型集合数据 -->
                <ref bean="user" />
                <ref bean="user" />
                <ref bean="user" />
            </list>
        </property>
    </bean>
 
    <!-- 利用无参构造建立实例对象 -->
    <bean name="customer2" class="cn.zz.spring.domain.Customer">
        <constructor-arg name="cname" value="李四"></constructor-arg>
        <constructor-arg index="1" value="lalala"></constructor-arg>
        <constructor-arg index="2" value="18"></constructor-arg>
        <!-- <constructor-arg name="cpassword" value="lalala"></constructor-arg>
        <constructor-arg name="age" value="18" type="int"></constructor-arg> -->
    </bean>
 
    <!--使用p名称空间进行属性注入 
        1.引入P名称空间:xmlns:p="http://www.springframework.org/schema/p"
        2.使用P名称空间
            *普通类型属性:    p:属性名称="值"
            *对象类型属性    p:属性名称-ref="beanId"
     -->
     <bean name="customerSupper" class="cn.zz.spring.domain.CustomerSupper" p:customer-ref="customer2" p:name="小黑"></bean>
     <!-- 使用SpEL(Spring Expression Language)方式进行属性注入
             SpEl是Spring3.x后的版本提供的方法
             设置普通值:value="#{'String'}"
             设置值对象中的的属性:value="#{BeanId.Attribute}"或者value="#{BeanId.methodName()}"
     -->
     <bean name="customerSupper2" class="cn.zz.spring.domain.CustomerSupper">
         <property name="customer" ref="#{'customer2'}"></property>
         <property name="name" value="#{customer2.getCname()}"></property>
     </bean>
     <!-- 引入另外一个applicattionContext文件,进行分模块管理classpath:表示类路径,可省略
                      在同一个applicationContext文件中,bean标签的id属性不可重复
                      在不一样的applicationContext文件中,bean标签的id属性可重复,后加载的会覆盖先加载的             
     -->
           <import resource="classpath:applicationContext2.xml"/>

</beans>java

2、利用注解方式进行Bean管理
1.作Spring的IOC注解开发,须要引入新的约束
<?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="cn.zz.spring"></context:component-scan>
    <!-- 开启注解扫描,但只会扫描属性上的注解 -->
     <!-- <context:annotation-config></context:annotation-config> -->
</beans>
 
2.利用注解方式建立对象
    在须要被建立的对象的类上添加注解
    

 

 设置该对象的一些属性
     @Scope(value="prototype")设置该对象为多实例对象
3.利用注解注入属性
    

 

    注入普通类型属性:在对应的属性上添加 @Value(value="xxx")注解,与xml中配置不一样,该方式不须要属性提供set方法;
    注入对象类型属性:@Autowired和@Qualifier联合使用注入多态类型属性(spring框架中的注解)
                                   @Autowired
                                   @Quakifier(value="BeanId")
                                  @Resource一个顶两(javax即java扩展功能中的注解,官方不建议使用)
                                            @Resource(name="BeanId")
 4.利用注解设置Bean实例的生命周期
    
             在对应要设置的方式的方法中添加对应的注解
通常建议使用xml配置的无参构造方式建立对象,能够自行定义各类属性,注解有必定局限性
AOP学习基础
AOP概念
   全称是Aspect-Oriented Programming,即面向切面的程序设计,底层使用动态代理实现
1、JDK代理,针对有接口的动态代理
public class TestDynamicProxy {
    public static void main(String[] args) {
        //1.得到一个已知实现类对象
        ILook look = new LookImpl();
        //2.利用proxy进行动态代理,获取代理类
        ILook look2 = (ILook) Proxy.newProxyInstance(look.getClass().getClassLoader(), look.getClass().getInterfaces(),new ProxyClass(look));
        look2.look();
    }
}
/**
 * InvocationHandler 是代理实例的调用处理程序 实现的接口
 * 即建立一个代理实例
 * @author ZZ
 *
 */
class ProxyClass implements InvocationHandler{
    //设置一个成员变量用来接收被代理类的对象,look即被代理对象
    ILook look;
    public ProxyClass(ILook look){
        this.look = look;
    }
    /**
     * proxy:表示当前这个代理类对象
     * method:表示当前方法
     * args:表示方法参数
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //加强指定的方法
        if("look".equals(method.getName())){
            System.out.println("加强look...");
            return null;
        }
        //放心其它的方法
        return method.invoke(look, args);
    }  
}
2、Cglib代理,针对没有接口的动态代理
public class TestCglibDynamicProxy {
    public static void main(String[] args) {
        //1.得到被代理的对象
        See see = new SeeChild();
        //建立一个Cglib动态代理类
        ProxyClassCglib pr = new ProxyClassCglib(see);
        //得到代理对象
        See creatSee = pr.creatSee();
        creatSee.see();
    }
}
class ProxyClassCglib implements MethodInterceptor{
    //1.建立一个用来接收代理类对象的成员变量
    private See see;
    //2.设置构造
    public ProxyClassCglib(See see){
        this.see = see;
    }
    /**
     * 加强指定方法
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        if("see".equals(method.getName())){
            /**
             * methodProxy.invokeSuper(proxy, args);
             * 执行当前代理类的父类中的see的对应方法
             * method.invoke(see, args);
             * 执行被代理类的对应方法
             */
            method.invoke(see, args);
            methodProxy.invokeSuper(proxy, args);
            System.out.println("加强see");
            return null;
        }
        return method.invoke(see, args);
    }
    //4.返回代理对象
    public See creatSee(){
        //1.建立Cglib核心文件
        Enhancer enhancer = new Enhancer();
        //2.设置父类(设置父类的话,若是设置为父类.class,能够在加强方法中便可调用当前类的方法,也能够调用代理类对应的方法;若是设置代理对象.class,则只能够在加强方法中执行代理对象中对应的方法)
        enhancer.setSuperclass(See.class);
        //3.设置回调Callback类型,Callback应该是个MethodInterceptor的父接口,没有源码、、
        enhancer.setCallback(this);
        //4.生成代理类
        See see = (See) enhancer.create();
        //返回代理对象
        return see;
    }
}       

 

Spring基于AspectJ的AOP开发
 
   
     1、操做术语
  
     2、xml方式操做AspectJ进行AOP开发
  
AspectJ表达式
                基本样式:execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
                经常使用表达式
                    1.得到指定方法
                    execution(* cn.zz.xxx.method(..))
                        * 表示访问修饰符和返回值类型是任意的,method(..)表示指定的方法名,参数任意
                    2.同理能够设置全部方法名,全部包各类。。。
                    execution(* *.*(..))即全部包中的全部方法
                    execution(* cn.zz.*.*(..)) 即zz包下的全部方法
                    3.execution(*.xxx*(..))方法名称是save开头作加强
                    4.execution(* cn.zz..*(..)zz包和其全部子包,孙包中的全部方法
                    5.excution(* cn.zz.xxx.Ixxx+.*(..)) 当前包下指定接口的全部实现类中的全部方法(-:暂时未知)
        3.通知类型           
<bean id="customer2" class="cn.zz.spring.domain.Customer2"></bean>
        <bean id="user2" class="cn.zz.spring.domain.User2"></bean>
    <aop:config>
        <aop:pointcut expression="execution(* cn.zz.spring.domain.User2.run(..))" id="p1"/>
        <aop:aspect ref="customer2">
            <aop:before method="run" pointcut-ref="p1"/>
        </aop:aspect>
    </aop:config>
    <aop:before>:前置通知
    <aop:aroubd>:环绕通知
<aop:after-returning>:后置通知
    <aop:after-throw>:异常通知
    <aop:after>:最终通知
     3、注解方式操做AspectJ进行AOP开发 
<!-- 配置开启AOP中的注解扫描 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>   
    在加强方法的类上添加注解@Aspect
    在对应方法上添加@Before,@After等等。。配置value="execution()"AspectJ表达式
     4、Spring整合Junit

    引入Spring-test.jar包
   在须要被建立的对象中设置两个注解
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
JdbcTemplate模板操做
     配置信息
<!-- 得到外部引入的方式的链接池配置参数 -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:c3p0.properties"></property>
    </bean>
    <!-- 得到外部文件的参数第二种方式
        <context:property-placeholder location="classpath:c3p0.properties"/>
     -->
    <!-- 配置链接池IOC -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${driver}"></property>
        <property name="jdbcUrl" value="${url}"></property>
        <property name="user" value="${username}"></property>
        <property name="password" value="${password}"></property>
    </bean>
    <!-- 配置JdbcTemplate -->
    <bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    测试代码
/**
     * 利用spring自带的链接池得到单个数据
     */
    @Test
    public void testDemo1(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql:///test_spring");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        JdbcTemplate template = new JdbcTemplate(dataSource);
        String sql = "select count(*) from customer";
        Integer i = template.queryForObject(sql, Integer.class);
        System.out.println(i);
    }
    /**
     * 利用C3P0链接池得到单个对象
     */
    @Test
    public void testDemo2(){
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        try {
            dataSource.setDriverClass("com.mysql.jdbc.Driver");
            dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test_spring");
            dataSource.setUser("root");
            dataSource.setPassword("root");
            JdbcTemplate template = new JdbcTemplate(dataSource);
            String sql = "select * from customer where cname=?";
            Customer customer = template.queryForObject(sql, new RowMapper<Customer>(){
                @Override
                public Customer mapRow(ResultSet set, int rows) throws SQLException {
                    Customer customer = new Customer();
                    String cname = set.getString("cname");
                    String address = set.getString("address");
                    customer.setCname(cname);
                    customer.setAddress(address);
                    return customer;
                }
            }, "网易");
            System.out.println(customer.getAddress());
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
    }
    /**
     * 利用IOC方式得到各个对象来得到对象集合
     */
    @SuppressWarnings("resource")
    @Test
    public void testDemo3(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        JdbcTemplate template = (JdbcTemplate) context.getBean("template");
        String sql = "select * from customer";
        List<Customer> list = template.query(sql, new RowMapper<Customer>(){
            @Override
            public Customer mapRow(ResultSet set, int rows) throws SQLException {
                String cname = set.getString("cname");
                String address = set.getString("address");
                Customer customer = new Customer();
                customer.setCname(cname);
                customer.setAddress(address);
                return customer;
            }
        });
        System.out.println(list);
    }
Spting事物操做
     事物的传播行为
         指在一个事物中调用另一个事物

利用配置文件控制事物和 事物的传播行为
    事物管理APIPlatformTransactionManager(事物管理器)
<!-- 配置JdbcTemplate -->
    <bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 配置Spring的JdbcTemplate模板的事物控制 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 配置事物加强 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>                  
                     <!-- method:指定要执行事物的方法名称
                 propagation:指定事物传播行为方式
                 isolation:指定事物的隔离级别
             -->
            <tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/>
        </tx:attributes>
    </tx:advice>
    <!-- 配置切面 -->
    <aop:config>
        <aop:pointcut expression="execution(* cn.zz.spring.service.*.*(..))" id="p1"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="p1"/>
    </aop:config> 
 
 利用注解控制事物和事物的传播行为
<!-- 开启IOC注解扫描 :只会扫描属性上的注解-->
    <context:annotation-config></context:annotation-config>
    <!-- 开启AOP注解扫描 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    <!-- 开启事物注解扫描 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <!-- 配置transactionManager的  -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    <!-- 配置C3P0的DataSource -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${driver}"></property>
        <property name="jdbcUrl" value="${url}"></property>
        <property name="user" value="${username}"></property>
        <property name="password" value="${password}"></property>
    </bean>
    <!-- 加载配置c3p0参数的Properties文件 -->
    <!-- <context:property-placeholder location="classpath:c3p0.properties"/> -->
        <!-- 得到外部引入的方式的链接池配置参数 -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:c3p0.properties"></property>
    </bean>
    <!-- 配置各类Bean信息 -->
    <bean id="userService2" class="cn.zz.spring.service2.UserService2"></bean>
    <bean id="userDao" class="cn.zz.spring.dao.UserDao"></bean>
    <bean id="template" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
 在须要进行事物控制的类或者方法上添加注解 @Transactional
相关文章
相关标签/搜索