你的位置:首页 > ASP.net教程

[ASP.net教程]spring一些方法和用法例子



分两大块 :

    1 控制反转 IOC : 控制类的实例化,以及他们的调用关系
    2 动态代理 AOP : 主要是事务机制的控制

//控制反转 : IOC(又叫DI)
////四种解析方式 :

    //四种方式获取属性 四种获取属性的方式
    //四种方式读取属性 四种读取属性的方式
    1 DOM : //把所有属性都弄到文档对象中,全部读取  一个报错,全部不读取
    2 JDOM : //把所有属性都弄到文档对象中,全部读取  一个报错,全部不读取
    3 DOM4J : //把所有属性都弄到文档对象中,全部读取  一个报错,全部不读取
    4 SAX : //用IO流,一个一个读取,读取一个,放进去一个 哪里报错,报错处往后就不读取,前面读取

        DOM :  == Document Object Model : 文档对象模型
        SAX : 基于事件和流的方式解析        sax,DOM : 这两种已经加入java的核心包,不再需要第三方宝
        JDOM : 是DOM的一种增强版本
        DOM4J : JDOM的一个子项目

//解析
        1 获得根节点
        2 遍历根节点里面的子节点
        3 获取子节点里面的属性
        4 遍历节点里面的内部(子节点)节点
        所以
//子节点和属性的区别 :

        <user id="2">//属性
            <name>图图</name>//子节点
        </user>
        子节点和属性本质一回事,都是保存数据的,只是根据不同的需求和数据的属性写到了不同的位置
        被描述的那个主题对象的内部属性,一般用节点声明
        不是主题对象内部属性,一般用属性声明

    //子节点的本质,属性的本质,子节点和属性的本质 :
            
        本质 : 都是保存数据的,只是根据不同的需求和数据的属性写到了不同的位置

DOM :

    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();//创建工厂对象,用于创建别的对象
    DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();//用工厂对象创建对象,用于调用方法,获取
    parse :

        //用于获取        Document document = documentBuilder.parse("
    getChildNodes :

        //获得所有文档里面的一级的子节点 返回值是NodeList类型(集合) 是上面的Document对象,调用的方法
        NodeList users = document.getChildNodes();//获得所有文档的子节点 ,  如 : body , head ...,这里是那些注释和<users> (任意写的标签)

    item :  

        //item(下标); 用NodeList的对象,调用这个方法,返回值是Node类型 获得集合上对应下标的元素
        Node user = users.item(i);// item(index)获得子节点 users  获得相应索引上面的元素,就是下标上面的元素

    getLength :
    
        //getLength() ; 用NodeList的对象,调用这个方法,返回值是int类型 获得集合的长度
        int i = users.getLength();//返回users集合(NodeList集合)的长度

    getNodeName :

        //getNodeName();//获得标签的名字,用Node对象调用这个方法,返回值是String
        String s = user.getNodeName();

    getTextContent :

        //getTextContent();//获得文本节点,用Node对象调用这个方法,返回值时String
        String s = user.getTextContent();

JDomDemo :

        SAXBuilder builder = new SAXBuilder();//创建工厂对象

    build :
         //用于获取        Document document = builder.build("
    getRootElement :

        //获得根节点,返回值时Element类型  是上面的Document的对象调用的这个方法
        Element users = document.getRootElement();//获得根节点

    getChildren :

        //获得里面的所有指定子节点 , 返回值是List类型,是上面Element的对象调用的这个方法
        List userList = users.getChildren("user");//获得里面所有的user子节点

    size :

        //返回集合里面的元素个数,返回值是int , 是上面List的对象调用的这个方法
        int i = userList.size();

    get :
        
        get();//根据下标获取指定的元素
        Element element = (Element) lists集合.get(下标);//获得单个的子节点里面的子节点里面的属性,强制转型为Element类型来接收

    getAttributeValue :

        //获得的是内部属性 如 : <user id="2" >  是获得这里面的id
        String id = element.getAttributeValue("id");    //获取节点的属性值(是属性,不是子节点),返回值是个字符串

    getName :

        getName();//获得属性的名字(标签名)
        String s = element.getName();//上面获得了节点里面的属性,这个是用那个节点的对象,调用方法,来获得节点的名字

    getValue :

        getValue();//获得属性的值(标签的值(就是文本节点))
        String s = element.getValue();//上面获得了节点里面的属性,这个是用那个节点对象,调用方法,来获得节点的值

Dom4JDemo :

    SAXReader saxReader = new SAXReader();//创建工厂
    File input    Document document = saxReader.read(input    Element users = document.getRootElement();//一级节点(users根节点)
for (Iterator i = users.elementIterator();     i.hasNext();) {//遍历
                    Element user = (Element) i.next();//二级节点
                    for (Iterator j = user.elementIterator(); j.hasNext();) {
                        Element node = (Element) j.next();//三级子节点
                        System.out.println(node.getName()+":"+node.getText());
                        
                    }
                    System.out.println();
                
            }
    elementIterator :

        //用Element对象调用这个方法elementIterator(),是元素的迭代器方法
        Interator j = user.elementIterator();//把每个元素,都给了 j

    hasNext :
        
        hasNext();//访问下位还有没有元素,指针在顶端,返回值为boolean  true/false
        j.hasNext();

    next :
        
        next();//获取下位元素
       Element node = (Element)j.next();//获取下一位的元素,然后转向为Element
    
    getName :

        getName();//获得元素的名字(就是标签名),用Element对象调用
        node.getName();//获得标签的名字

    getText :
        
        getText();//获得标签/属性的值(文本节点的内容)
        node.getText();//用Element对象调用这个方法

SAX :

    类必须继承DefaultHandler
    startDocument()//开始读取的时候,自动调用的方法
    endDocument()//读取结束的时候,自动调用的方法

    getLength :
        
        Attributes 类型的对象,调用这个方法
        attributes.getLength();//获得属性的长度

    getQName :

         Attributes 类型的对象,调用这个方法
        attributes.getQName(0);//获得属性的名字
    
    getValue :
        
         Attributes 类型的对象,调用这个方法
        attributes.getValue(0);//获得属性的值
        

getBean :

    getBean("ID/name");//获得
@Component :

    写在类上面,就会实例化当前类
     1 @Component  实例化当前类并使用默认名字
     2 @Component("userDAO") 实例化当前类,并指定名字
     3 @Component(value="userDAO")  实例化当前类并指定名字

@Autowired

    //写在,在当前类中,保存别的类的引用的成员变量,对应的set**();方法上
        从容器里面找一个和这个参数类型对应的bean注入进来,注意和beans.        Autowired: 默认是byType的,可能是多个的问题,但是容易出现重复,这个可以解决,但是4.0不写也没问题
        @Qualifier用法 就会去对        @Autowired
        public void set***(@Qualifier("
@Resource(name="userDAO")

     //写在,在当前类中,保存别的类的引用的成员变量,对应的set**();方法上
        这里引用了一个资源,默认是byName;当名字找不到的时候,就byType,可以指定一个名字
        在JSR-250中,当你要用注解的方式声明一个按照名字装配的bean的时候,强烈建议用resource而不是autowire,即使指定@Qualifier 在对应方法形参列表里面(@Qualifier("        但是按照byType(按照类名,class属性的时候),用autoWire

//AOP : 动态代理
AOP :

        // 产生个代理对象
        // 1 要产生对象--->是不是要先用***.class---->ClassLoader,产生***.class
        // 要求,被代理对象和代理独享的ClassLoader必须是同一个,要不然互相之间访问不了,**.class
        // 带来对象内部还包含了一个代理对象,所以是同一个ClassLoader
        // 2 产生被代理对象所实现的接口,代理对象也要实现相同的接口
        // 3 产生代理对象以后,要调用代理里面的方法,谁来处理,就是那个handler

        // 用什么产生代理对象: Proxy.newProxyInstance
        // 这里只是一种机制而已,具体的代理的代理对象和被代理对象,是你自己实现处理的
        // 写多少就代理多少

        //目标是获得代理的那个对象,被代理类的接口的加载器,就是代理类加载器,因为这个代理类是自动生成的
        
    LogInterceptor li = new LogInterceptor();//代理类,有所有接口的时候,的引用
    UserDAO userDAOProxy = (UserDAO) Proxy.newProxyInstance(userDAO.getClass().getClassLoader(),new Class[] { UserDAO.class }, li);//确定接口  三个参数 (加载器 , 被代理类的父接口(实现的接口的Class对象(**.class)) , 代理类的对象 )  获得的就是指定接口的代理类的对象,是虚拟的

    userDAOProxy.save(new User());//确定方法  用那个虚拟的指定了接口的代理类的对象,调用方法.调用什么方法,代理的就是什么方法,这里代理的是save()方法

    然后会去调用代理类的invoke()方法,并且把上面的那个userDAOProxy.save(new User()) ,当做参数列表传过去 , 代理类的invoke方法有三个参数 :
                1 对象 指定了接口的代理类的对象(虚拟的,不能用)
                2 方法名 (这里是save , 但是底层经过处理,把方法名,弄成了method的对象)
                3 参数 ( Object[] args  别管传什么对象过去,Object类型的数组,都能接下,并向上转型了吧)

    // <aop:aspectj-autoproxy />// 这是AOP的自动配置 和IOC/DI的强注释,没有任何关系

@Aspect :

     @Aspect : 在类的上面写上这个标签,就说明是使用注解方式 AOP

@PostConstruct :

         @PostConstruct 写在init()方法上面 就是执行的时候(实例化当前类的时候),先自动调用此方法

@PreDestroy :

        @PreDestroy 写在destory()方法上面,调用执行此方法,创建的那个对象销毁
            如果,                                prototype 的时候(要多少对象,就创建多少对象) 调用此方法,也不会销毁对象

@Pointcut :
    
    Spring(IOC),用注解的时候,每个类型的类都有固定的修饰符修饰,
    @Controller(Action),@Service(service),@Repository(DAO),@Component(model,能修饰所有类)
    这样以后,所有的类都可以纳入spring的控制范畴
 
    pointcut : 实际是指方法调用的时候
    advice : 方法调用前后执行代码
     @Pointcut : advice+pointcut 针对某一个方法,和另一个方法的交界处,切断,拦截,并由这个地方,链接这两个方法 ,后面那个是指定代理的方法(public *(返回值) 包..*(某个包里面的所有类).方法名(..(参数列表) ) )  这个注解,写在哪个方法上面,就用这个方法,代替需要代理的方法
     写法 , 如 :
        @Pointcut("execution(public * com.jaovo.service..* .add(..))") //那么这个方法,就代替add()方法,如果想在add()方法调用前后执行别的东西,就用@Before,@After,@Around

Advice :
    
    @Before(前),@AfterReturning(返回值后),@AfterThrowing(异常后),@After(后),@Around(前后)
    方法调用前后执行代码
@Before :

    @Before : 执行指定方法之前,就执行的方法
    @Before("被代理的方法/代替被代理的方法")//在被代理方法调用执行之前,先执行用@Before修饰的方法

    @Before("execution(public void com.jaovo.dao.impl.UserDAOImpl.save(com.jaovo.model.User))")//这是指定了某个方法,公共的,没有返回值的,UserDAOImpl类里面的save()方法,并且这个方法的参数是User类型 , 再某个方法上面写了这个,就是说,这个save()方法执行之前,先执行用@Before修饰的方法

    @Before("execution(public * com.jaovo.dao..*.*(..))")//指定了,公共的 任意返回值的,dao包下的任意包,任意类,任意方法,任意形参列表 , 调用这些方法的时候,就会先执行用@Before修饰的方法

    @Before("myMethod()")//这个就是当代替被代理方法的这个方法执行前,.先执行用@Before修饰的方法

@After :

    @After : 执行指定方法完毕,就执行的方法
    @After("被代理的方法/代替被代理的方法")//在被代理方法运行结束,就执行用@After修饰的方法
    操作步骤和上面的@Before的几个例子一样

@Around :

    @Around : 这方法里面,是真正的调用被代理的方法
    写法 , 如 :
        @Around("myMethod()")//这方法里面,是真正的调用被代理的方法,
    public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("method around start-----1");
        pjp.proceed();// 开始执行,被代理的方法 这才是真正的调用add()方法 并且,以后的代码,都默认添加在add()方法的方法体里面,追加的内容
        System.out.println( "我会被默认融为被代理的方法中" );
        }
}

@AfterReturning :

    @AfterReturning("被代理的方法/代替被代理方法的方法")//当里面指定的方法返回值返回来之后,就执行用@AafterReturning修饰的方法

    @AfterReturning("execution(public * com.jaovo.dao..*.*(..))")//这个是用截断某个包里面的所有方法,当这些方法返回值的时候,就执行此方法
    @AfterReturning("myMethod()")//这个是绑定了代替被代理方法的方法,当被代理方法执行完成,返回值的时候,就执行用@AfterReturning修饰的方法

@AfterThrowing :

    @AfterThrowing("被代理的方法/代替被代理方法的方法")//当里面指定的方法报异常之后,就执行用@AafterThrowing修饰的方法

     @AfterReturning("execution(public * com.jaovo.dao..*.*(..))")//这个是用截断某个包里面的所有方法,当这些方法报异常的时候,就执行此方法
    @AfterReturning("myMethod()")//这个是绑定了代替被代理方法的方法,当被代理方法报异常的时候,就执行用@AfterThrowing修饰的方法

@Transactional :

    //设置回滚  写到某个方法的上面 就会对这个方法的执行,添加回滚(方法开始,会自动添加回滚点,如果报错,会直接跳回回滚点,就是方法开始执行的地方)
    
    @Transactional(可以写两个值) :
                1 propagation=Propagation.值 //这种是设置回滚(事务)的模式

                       Propagation.REQUIRED  //这种,就相当于包含,由这个事务,一直跟着走,只要有一个地方报错,就立刻跳回调用这个方法的地方(就是添加事务设置回滚的地方)

                       Propagation.REQUIRES_NEW  //这种是 , 执行一次方法,就添加一个新的事务(回滚点,谁的谁谁的都没有关系,有地方错了之后,那个事务错了,就跳回那个事务回滚点那个地方,并不用跳回第一个添加的那个回滚点)
                       Propagation.MANDATORY
                       Propagation.NESTED
                       Propagation.NOT_SUPPORTED //这个方法就不会支持事务,不会被添加回滚点(一般用这个的时候,都是和readOnly=true一起用的,为了数据安全,让那些不支持事务的方法,设置只读模式,就是不可以更改数据(不可以增删改) 只能查)
                       Propagation.SUPPORTS  

                2 readOnly = true //这种是设置为只读模式,不能进行增删改