• 第六届中国创业投资高峰论坛在深成功举行 2019-05-23
  • 如何制订企业发展计划 2019-05-09
  • 酒成为5月基金上涨最大功臣,白酒行情景气?白酒 基金 2019-05-09
  • 日研究用iPS细胞再现小脑疾病成因 2019-04-30
  • 万水千山粽是情 带你了解端午节民俗文化——黄河新闻网 2019-04-30
  • 端午节起中国公民出入境通关排队不超过30分钟 2019-04-27
  • 物智 —频道 春城壹网 七彩云南 一网天下 2019-04-19
  • 西藏职业技术学院全面推进毕业生就业创业 2019-04-19
  • 南瓜子营养价值高 这样吃最健康-美食资讯 2019-04-15
  • 国家统计局:5月份能源生产总体平稳 2019-04-15
  • 衔接“新高考” 要求变更高 2019-03-26
  • 上交所向“中技系”两公司下发监管工作函 2019-03-24
  • 对,这实质上是货币战争。美国的这些行动是要让前些年泛滥发行的美元裹携各国人民的血汗回流美国,经济的、军事的、政治的手段都要用上,中国对此要有足够的准备。 2019-03-24
  • 新疆公益组织,公益求助,晨报救命血联盟 2019-03-21
  • 以新的更大作为发挥广东两个重要窗口作用 2019-03-21
  • 天天彩选四开奖结果:Spring框架入门

    今天上海选四开奖号码 www.kcnj.net

    Spring框架入门


    Spring框架

    一、什么是Spring 

    ? ? ?Spring框架是由于软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅仅限于服务器端的开发。从简单性、可测试性和松耦合性角度而言,绝大部分Java应用都可以从Spring中受益。Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器框架。
     ◆目的:解决企业应用开发的复杂性
     ◆功能:使用基本的JavaBean代替EJB,并提供了更多的企业应用功能
     ◆范围:任何Java应用
                                                                      ----------------百度百科
    二、什么是IOC
      控制反转(Inversion of Control,英文缩写为IoC)把创建对象的权利交给框架,是框架的重要特征,并非面向对象编程的专用术语。它包括依赖注入和依赖查找。传统的业务层,当需要资源时就在该业务层new资源,这样耦合性(程序之间相互依赖关联)较高。现在将new的部分交给spring,做到高内聚低耦合。简而言之:原先是每当调用dao层或service层方法时,由appnew,现在是将new的权利交给spring,要什么资源从spring中获??!
    ?
    三、快速搭建框架环境
      1.下载框架所需的依赖jar包
      ?spring官网为://spring.io/
       下载jar包: ??//repo.springsource.org/libs-release-local/org/springframework/spring
       2.导入基本jar包
      ?

       其实基本核心jar有beans;context;core;expression包,其他是依赖log4j日志。当然spring的jar不止这些,后期慢慢加上。

      3.配置log4j配置文件

       日志文件定义在src目录下

    ### direct log messages to stdout ###
    log4j.appender.stdout=org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target=System.err
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
    
    ### direct messages to file mylog.log ###
    log4j.appender.file=org.apache.log4j.FileAppender
    log4j.appender.file.File=c:mylog.log
    log4j.appender.file.layout=org.apache.log4j.PatternLayout
    log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
    
    ### set log levels - for more verbose logging change "info" to "debug" ###
    
    log4j.rootLogger=info, stdout

      4.测试日志文件是否部署成功

    package com.clj.demo1;
    
    import org.apache.log4j.Logger;
    import org.junit.Test;
    
    /**
     * 演示日志用法
     * @author Administrator
     *
     */
    public class Demo1 {
        //创建日志类
        private Logger log=Logger.getLogger(Demo1.class);
        @Test
        public void run1(){
            //可以将log4j.rootLogger属性中的info改为off则不会再控制台显示
            log.info("执行了");
        }
    }

      5.定义一个接口和实现类

       接口:

    package com.clj.demo2;
    
    public interface UserService {
        public void sayHello();
    }

       实现类

    package com.clj.demo2;
    
    public class UserServiceImpl implements UserService{
        private String name;
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public void init(){
            System.out.println("初始化。。");
        }
        public void sayHello() {
            System.out.println("Hello Spring"+"	"+name);
        }
        public void destory(){
            System.out.println("销毁。。");
        }
    
    }

      6.定义spring专属的配置文件

       ?定义名为applicationContext.xml,位置为src下,与日志文件同目录,导入相对应的约束,并将实现类注入到配置文件中

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="//www.springframework.org/schema/beans"
        xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
        xmlns:p="//www.springframework.org/schema/p"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans.xsd">
         <!-- 使用bean标签  
             1.id值唯一(必写)
            2.注意:class为实现类路径,不是接口(必写)
            3.init-method核心方法执行之前初始化工作(选写)
            4.destroy-method核心方法执行之后初始化工作(选写)-->
         <bean id="userService" class="com.clj.demo2.UserServiceImpl" init-method="init" destroy-method="destory">
             <property name="name" value="佳先森"></property>
         </bean>
    </beans>

       7.测试

    public class Demo1 {
        /**
         * 原始方式
         */
        @Test
        public void run(){
            //创建实现类
            UserServiceImpl s=new UserServiceImpl();
            s.setName("佳先森");
            s.sayHello();
        }
        /**
         * 老的工厂版本BeanFactory
         * 旧的工厂不会创建配置文件对象
         */
        @Test
        public void run2(){
            BeanFactory factory=new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
            UserService us=(UserService)factory.getBean("userService");
            us.sayHello();
        }
        /**
         * 使用spring框架IOC方式
         * 新版本factory创建启动服务器会创建配置文件对象,再次调用时无需加载工厂
         */
        @Test
        public void run3(){
            //创建工厂,加载核心配置文件(ClassPathXmlApplicationContext从src下找)
            ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
            //从工厂中获取到对象(配置文件中的id值,这里用了多态)
            UserService usi=(UserService) ac.getBean("userService");
            //调用对象的方法执行
            usi.sayHello();
        }
        /**
         * 演示destroy-method方法
         * bean摧毁方法不会自动执行
         * 除非scope= singleton或者web容器中会自动调用,但是main函数或测试用例需要手动调用(需要使用ClassPathXmlApplicationContext的close()方法)
         */
        @Test
        public void run4(){
            //创建工厂,加载核心配置文件(ClassPathXmlApplicationContext从src下找)
            ClassPathXmlApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
            //从工厂中获取到对象(配置文件中的id值,这里用了多态)
            UserService usi=(UserService) ac.getBean("userService");
            //调用对象的方法执行
            usi.sayHello();
            //ApplicationContext实现类提供close方法,将工厂关闭就可执行destory-method方法
            ac.close();
        }
    }

    ?   其中旧工厂与新工厂的区别?

    ? ? ? ? * BeanFactory和ApplicationContext的区别

    ????????* BeanFactory ??????????????-- BeanFactory采取延迟加载,第一次getBean时才会初始化Bean

    ????????* ApplicationContext ? ? ?-- 在加载applicationContext.xml时候就会创建具体的Bean对象的实例,还提供了一些其他的功能

    ????????????* 事件传递

    ????????????* Bean自动装配

    ????????????* 各种不同应用层的Context实现

      总结:这是个最基本的demo,是将实现类配置到了spring配置文件中,每次启动服务器时,就会加载配置文件,从而实例化了实现类

    四、spring之依赖注入

      1、什么是依赖注入?

      Spring 能有效地组织J2EE应用各层的对象。不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的 管理下有机地协调、运行。Spring将各层的对象以松耦合的方式组织在一起,Action对象无须关心Service对象的具体实现,Service对 象无须关心持久层对象的具体实现,各层对象的调用完全面向接口。当系统需要重构时,代码的改写量将大大减少。依赖注入让bean与bean之间以配置文件组织在一起,而不是以硬编码的方式耦合在一起。理解依赖注入

    ? ? 依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。

    不管是依赖注入,还是控制反转,都说明Spring采用动态、灵活的方式来管理各种对象。对象与对象之间的具体实现互相透明。  

      2. IOC和DI的概念

      * IOC -- Inverse of Control,控制反转,将对象的创建权反转给Spring??!

      * DI -- Dependency Injection,依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件中??!

      3.演示

      对于类成员变量,常用的注入方式有两种

    ? ? ? ?属性set方法注入和构造方法注入

    ? ? ? 先演示第一种:属性set方法注入

       1)持久层

    package com.clj.demo3;
    
    public class CustomerDaoImpl {
        public void save(){
            System.out.println("我是持久层的Dao");
        }
    }

       2)业务层

       注意:此时是想将持久层注入到业务层,将创建持久层实例权利交给框架,条件是业务层必须提供持久层的成员属性和set方法

    package com.clj.demo3;
    /**
     * 依赖注入之将dao 层注入到service层
     * @author Administrator
     *
     */
    public class CustomerServiceImpl{
        //提供成员属相,提供set方法
        private CustomerDaoImpl customerDao;
        
        public void setCustomerDao(CustomerDaoImpl customerDao) {
            this.customerDao = customerDao;
        }
    
        public void save(){
            System.out.println("我是业务层的service...");
            //1.原始方式
            //new CustomerDaoImpl().save();
            
            //2.spring 之IOC方式
            customerDao.save();
        }
    }

       3)配置文件配置

     <!-- 演示依赖注入 -->
         <bean id="customerDao" class="com.clj.demo3.CustomerDaoImpl"/>
         <bean id="customerService" class="com.clj.demo3.CustomerServiceImpl">
                 <!-- 将Dao注入到service层 -->
                <property name="customerDao" ref="customerDao"></property>
         </bean>

       4)测试

    /**
         * spring 依赖注入方式
         * 将dao层注入到service层
         */
        @Test
        public void run2(){
            //创建工厂,加载配置文件,customerService被创建,从而也创建了customerDao
            ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
            CustomerServiceImpl csi=(CustomerServiceImpl) context.getBean("customerService");
            csi.save();
        }

       第二种:构造方法注入

      1)pojo类并提供构造方法

    package com.clj.demo4;
    /**
     * 演示的构造方法的注入方式
     * @author Administrator
     *
     */
    public class Car1 {
        private String cname;
        private Double price;
        public Car1(String cname, Double price) {
            super();
            this.cname = cname;
            this.price = price;
        }
        @Override
        public String toString() {
            return "Car1 [cname=" + cname + ", price=" + price + "]";
        }
        
    }

       2)配置文件配置

             <!-- 演示构造方法注入方式 -->
         <bean id="car1" class="com.clj.demo4.Car1">
             <!-- 写法一<constructor-arg name="cname" value="宝马"/>
             <constructor-arg name="price" value="400000"/> -->
             <!--写法二 -->
             <constructor-arg index="0" value="宝马"/>
             <constructor-arg index="1" value="400000"/>
           </bean>      

      3)测试

        @Test
        public void run1(){
            ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
            Car1 car=(Car1) ac.getBean("car1");
            System.out.println(car);
        }

      ? 拓展:构造方法之将一个对象注入到另一个对象中

       1)pojo类:目的:将上列中的车注入到人类,使之成为其中一个属性,则必须在此类中提供车的成员属性,并提供有参构造方法

    package com.clj.demo4;
    
    public class Person {
        private String name;
        private Car1 car1;
        public Person(String name, Car1 car1) {
            super();
            this.name = name;
            this.car1 = car1;
        }
        @Override
        public String toString() {
            return "Person [name=" + name + ", car1=" + car1 + "]";
        }
        
        
    }

       2)配置文件

             <!-- 构造方法之将一个对象注入到另一个对象-->
         <bean id="person" class="com.clj.demo4.Person">
             <constructor-arg name="name" value="佳先森"/>
             <constructor-arg name="car1" ref="car1"/>
         </bean>         

      4.如何注入集合数组

       1)定义pojo类

    package com.clj.demo4;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    import java.util.Set;
    
    /**
     * 演示集合注入的方式
     * @author Administrator
     *
     */
    public class User {
        private String[] arrs;
        private List<String> list;
        private Set<String> sets;
        private Map<String,String> map;
        private Properties pro;
        
        public void setPro(Properties pro) {
            this.pro = pro;
        }
    
        public void setSets(Set<String> sets) {
            this.sets = sets;
        }
    
        public void setMap(Map<String, String> map) {
            this.map = map;
        }
    
        public void setList(List<String> list) {
            this.list = list;
        }
    
        public void setArrs(String[] arrs) {
            this.arrs = arrs;
        }
    
        @Override
        public String toString() {
            return "User [arrs=" + Arrays.toString(arrs) + ", list=" + list
                    + ", sets=" + sets + ", map=" + map + ", pro=" + pro + "]";
        }  
    }

      2)配置文件

         <!-- 注入集合 -->
         <bean id="user" class="com.clj.demo4.User">
             <!-- 数组 -->
             <property name="arrs">
                 <list>
                     <value>数字1</value>
                     <value>数字2</value>
                     <value>数字3</value>
                 </list>
             </property>
             <!-- list集合 -->
             <property name="list">
                 <list>
                     <value>金在中</value>
                     <value>王杰</value>
                 </list>
             </property>
             <!-- set集合 -->
             <property name="sets">
                 <set>
                     <value>哈哈</value>
                     <value>呵呵</value>
                 </set>
             </property>
             <!-- map集合 -->
             <property name="map">
                 <map>
                     <entry key="aa" value="rainbow"/>
                     <entry key="bb" value="hellowvenus"/>
                 </map>
             </property>
             <!-- 属性文件 -->
             <property name="pro">
                 <props>
                     <prop key="username">root</prop>
                     <prop key="password">123</prop>
                 </props>
             </property>
         </bean>

       3)测试

        /**
         * 测试注入集合
         */
        @Test
        public void run3(){
            ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
            User user= (User) ac.getBean("user");
            System.out.println(user);
        }

       5.怎么分??榭?/span>

       在主配置文件加入<import>标签假如此时在com.clj.test包下定义了一个配置文件applicationContext2.xml

        <!-- 分??榭⒅肫渌渲梦募?-->
         <import resource="com/clj/test/applicationContext2.xml"/>

    五、详解Spring框架的IOC之注解方式

      1、入门

      1).导入jar包

       除了先前6个包,玩注解还需一个spring-aop

      

      2).持久层和实现层(这里忽略接口)

       持久层

    package com.clj.demo1;
    
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Repository;
    /**
     * UserDaoImpl交给IOC的容器管理
     * @author Administrator
     *
     */
    public class UserDaoImpl implements UserDao{
    
        @Override
        public void save() {
            System.out.println("保存客户。。");
            
        }
    
    }

       业务层

    package com.clj.demo1;
    
    import javax.annotation.PostConstruct;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;

    public class UserServiceImpl implements UserService{

    @Override public void sayHello() { System.out.println("Hello spring"+name); } }

       3).定义配置文件

       此时约束条件需添加context约束,并添加组件扫描

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="//www.springframework.org/schema/beans"
        xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
        xmlns:context="//www.springframework.org/schema/context" xsi:schemaLocation="
            http://www.springframework.org/schema/beans //www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context //www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
        <!-- 开启注解扫面 :base-package指定扫面对 包-->
        <context:component-scan base-package="com.clj.demo1"/>
    </beans>

      4)在实现类中添加注解

    /**
     * 组件注解,可以用来标记当前的类
     * 类似<bean id="userService" class="com.clj.demo1.UserServiceImpl">
     * value表示给该类起个别名
     */
    @Component(value="userService")
    public class UserServiceImpl implements UserService{
                //省略
    }

      5)编写测试

        /**
         * 注解方式
         */
        @Test
        public void run2(){
            ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
            UserService us=(UserService) ac.getBean("userService");
            us.sayHello();
        }

      2.关于bean管理常用属性

    1. @Component:组件.(作用在类上)  最原始的注解,所有需要注解的类都写这个没问题,他是通用的
    2. Spring中提供@Component的三个衍生注解:(功能目前来讲是一致的)
        * @Controller       -- 作用在WEB层
        * @Service          -- 作用在业务层
        * @Repository       -- 作用在持久层
        * 说明:这三个注解是为了让标注类本身的用途清晰,Spring在后续版本会对其增强
     
    3. 属性注入的注解(说明:使用注解注入的方式,可以不用提供set方法)
        * 如果是注入的普通类型,可以使用value注解
        * @Value             -- 用于注入普通类型
        * 如果注入的是对象类型,使用如下注解
            * @Autowired        -- 默认按类型进行自动装配   匹配的是类型,与注入类的类名无关
                * 如果想按名称注入
                * @Qualifier    -- 强制使用名称注入            必须与Autowired一起用,指定类名,与注入的类名有关
            * @Resource         -- 相当于@Autowired和@Qualifier一起使用
            * 强调:Java提供的注解
            * 属性使用name属性

    4. Bean的作用范围注解

    ????* 注解为@Scope(value="prototype"),作用在类上。值如下:

    ????????* singleton ????-- 单例,默认值

    ????????* prototype ????-- 多例

    ?

    5. Bean的生命周期的配置(了解)

    ????* 注解如下:

    ????????* @PostConstruct ???-- 相当于init-method

    ????????* @PreDestroy ??????-- 相当于destroy-method

      1.演示属性对象注解

       条件:采用扫描的方式将属性(name)和对象(userDaoImpl)注入到业务层中

      1)持久层开启注解扫描Repository

    //@Component(value="userDao")通用类注解
    @Repository(value="ud")
    public class UserDaoImpl implements UserDao{
        @Override
        public void save() {
            System.out.println("保存客户。。");    
        }
    }

       2)业务层针对属性和对象提供注解

    package com.clj.demo1;
    
    import javax.annotation.PostConstruct;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    /**
     * 组件注解,可以用来标记当前的类
     * 类似<bean id="userService" class="com.clj.demo1.UserServiceImpl">
     * value表示给该类起个别名
     */
    //@Scope(value="grototype")多列的(singletype为单列)
    @Component(value="userService")
    public class UserServiceImpl implements UserService{
        //属性注解:相当于给name属性注入指定的字符串,setName方法可以省略不写
        @Value(value="佳先森")
        private String name;
        
        /**
         * 引用注入方式一:Autowired()
         * 引用注入方式二:Autowired()+Qualifier
         * 引用注入方式三:@Resource(name="userDao") java方式,按名称识别注入
         */
        //Autowired()按类型自动装配注入(缺点:因为是按类型匹配,所以不是很准确)
        @Autowired()
        @Qualifier(value="ud")  //按名称注入,得与Autowired一起用,两者一起能指定类
        private UserDao userDao;
        //注意Qualifier中的value是指定UserDaoImpl类名顶上的注解名,也可以指定配置文件中bean的id名
        
        
        /*public void setName(String name) {
            this.name = name;
        }*/
    
        @Override
        public void sayHello() {
            System.out.println("Hello spring"+name);
            userDao.save();
        }
        //@PostConstruct标签用于action生命周期中初始化的注解
        @PostConstruct
        public void init(){
            System.out.println("初始化...");
        }
    }

      注意:至于集合还是推荐使用配置文件方式

      2.Spring框架整合JUnit单元测试

      1)添加单元测试所需依赖包spring-test.jar

      

      注意:基于myeclipes自带Junit环境,但是有时因为版本问题,可能需要比较新的Junit环境,这里我在网上下了一个教新的 Junit-4.9的jar包,如果myeclipes较新的话无须考虑

      2)编写测试类,添加相对应的注解

      [email protected]与@ContextConfiguration(此是用于加载配置文件,因为默认从WebRoot路径为一级目录,加上此是认定src为一级目录)

    package com.clj.demo2;
    
    import javax.annotation.Resource;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import com.clj.demo1.UserService;
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:applicationContext.xml")
    public class Demo2 {
        @Resource(name="userService")
        private UserService userService;
        @Test
        public void run1(){
            userService.sayHello();
        }
    }

    六.spring框架之AOP

      1.什么是AOP

    ? ? ? ??* 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,功能??榛?/span>

    ? ? ? ? * AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构

    ? ? ? ? * AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范

    ? ? ? ? * 通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术

    ? ? ? ? * AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型

    ? ? ? ? * 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率?

      ? ? AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视、事务管理、安全检查、缓存)

      2. 为什么要学习AOP

    ? ? ? ? * 可以在不修改源代码的前提下,对程序进行增强??!(为固定的方法生成一个代理,在访问该方法之前,先进入代理,在代理中,可以编写更多的功能,使之方法的功能更强,使得程序进行增 ? ? ? ?强)

    ? ? ? ? Aop:面向切面编程,将一切事??榛?,每个??楸冉隙懒?,??榭梢怨灿茫ㄏ嗤模?,不同的格外自定义。用此替代传统的面向纵向编程,提高程序的可重用性

      3.AOP的实现(实现原理)

       Aop的实现包含两种代理方式<1>实现类接口:采用JDK动态代理<2>未实现类接口:采用CGLIB动态代理

       1.实现JDK动态代理

      ? 1)定义持久层接口实现类

    ?

    package com.clj.demo3;
    
    public interface UserDao {
        public void save();
        public void update();
    }
    package com.clj.demo3;
    
    public class UserDaoImpl implements UserDao {
    
        @Override
        public void save() {
            System.out.println("保存用户");
        }
        @Override
        public void update() {
            System.out.println("修改用户");
        }
    }

    ?

       2)定义JDK动态代理工具类

       ? ? 此工具类是在执行持久层save方法时增加一些功能,在开发中做到在不更改源码情况下增强某方法

    package com.clj.demo3;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * 使用JDK的方式生成代理对象(演示AOP原理)
     * @author Administrator
     *
     */
    public class MyProxyUtils {
        public static UserDao getProxy(final UserDao dao){
            //使用Proxy类生成代理对象
            UserDao proxy=(UserDao)Proxy.newProxyInstance(dao.getClass().getClassLoader() , dao.getClass().getInterfaces(),new InvocationHandler() {
                //只要代理对象一执行,invoke方法就会执行一次
                public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable {
                    //proxy代表当前代理对象
                    //method当前对象执行的方法
                    //args封装的参数
                    //让到类的save或者update方法正常执行下去
                    if("save".equals(method.getName())){
                        System.out.println("执行了保存");
                        //开启事务
                    }
                    return method.invoke(dao, args);
                }
            });
            return proxy;
        }
    }

       3)测试

    package com.clj.demo3;
    
    import org.junit.Test;
    
    public class Demo1 {
        @Test
        public void run1(){
            //获取目标对象
            UserDao dao=new UserDaoImpl();
            dao.save();
            dao.update();
            System.out.println("===============");
            //使用工具类,获取到代理对象
            UserDao proxy=MyProxyUtils.getProxy(dao);
            //调用代理对象的方法
            proxy.save();
            proxy.update();
            
        }
    }

       2.实现CGLIB技术

       ?1)定义持久层,此时没有接口

    package com.clj.demo4;
    
    public class BookDaoImpl {
        public void save(){
            System.out.println("保存图书");
        }
        public void update(){
            System.out.println("修改图书");
        }
    }

       2)编写工具类

    package com.clj.demo4;
    
    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    /**
     * Cglib代理方式实现原理
     * @author Administrator
     *
     */
    public class MyCglibUtils {
        /**
         * 使用CGLIB方式生成代理对象
         * @return
         */
        public static BookDaoImpl getProxy(){
            Enhancer enhancer=new Enhancer();
            //设置父类
            enhancer.setSuperclass(BookDaoImpl.class);
            //设置回调函数
            enhancer.setCallback(new MethodInterceptor() {
                
                @Override
                public Object intercept(Object obj, Method method, Object[] objs,
                        MethodProxy methodProxy) throws Throwable {
                    if(method.getName().equals("save")){
                    System.out.println("我保存了");
                    System.out.println("代理对象执行了");
            }
                    return methodProxy.invokeSuper(obj, objs);//是方法执行下去
                }
            });
            //生成代理对象
            BookDaoImpl proxy=(BookDaoImpl) enhancer.create();
            return proxy;
        }
    }

       3)编写测试类

    package com.clj.demo4;
    
    import org.junit.Test;
    
    public class Demo1 {
        @Test
        public void run1(){
            //目标对象
            BookDaoImpl dao=new BookDaoImpl();
            dao.save();
            dao.update();
            System.out.println("==========");
            BookDaoImpl proxy=MyCglibUtils.getProxy();
            proxy.save();
            proxy.update();
        }
    }

       3、Spring基于AspectJ的AOP的开发(配置文件方式)

      ?

    ?

    ?  1)部署环境,导入相对应的jar包

      ?

      2)创建配置文件,并引入AOP约束

     <beans xmlns="//www.springframework.org/schema/beans"
               xmlns:xsi="//www.w3.org/2001/XMLSchema-instance"
               xmlns:aop="//www.springframework.org/schema/aop"
               xsi:schemaLocation="
                http://www.springframework.org/schema/beans //www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/aop //www.springframework.org/schema/aop/spring-aop.xsd">

      3)创建接口和实现类

    package com.clj.demo5;
    
    public interface CustomerDao {
        public void save();
        public void update();
    }
      

    Comments are closed.

  • 第六届中国创业投资高峰论坛在深成功举行 2019-05-23
  • 如何制订企业发展计划 2019-05-09
  • 酒成为5月基金上涨最大功臣,白酒行情景气?白酒 基金 2019-05-09
  • 日研究用iPS细胞再现小脑疾病成因 2019-04-30
  • 万水千山粽是情 带你了解端午节民俗文化——黄河新闻网 2019-04-30
  • 端午节起中国公民出入境通关排队不超过30分钟 2019-04-27
  • 物智 —频道 春城壹网 七彩云南 一网天下 2019-04-19
  • 西藏职业技术学院全面推进毕业生就业创业 2019-04-19
  • 南瓜子营养价值高 这样吃最健康-美食资讯 2019-04-15
  • 国家统计局:5月份能源生产总体平稳 2019-04-15
  • 衔接“新高考” 要求变更高 2019-03-26
  • 上交所向“中技系”两公司下发监管工作函 2019-03-24
  • 对,这实质上是货币战争。美国的这些行动是要让前些年泛滥发行的美元裹携各国人民的血汗回流美国,经济的、军事的、政治的手段都要用上,中国对此要有足够的准备。 2019-03-24
  • 新疆公益组织,公益求助,晨报救命血联盟 2019-03-21
  • 以新的更大作为发挥广东两个重要窗口作用 2019-03-21