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
相關文章
相關標籤/搜索