Spring4 注解高级应用

来源:互联网 发布:淘宝自动浏览收藏软件 编辑:程序博客网 时间:2024/06/08 09:04

一、        关于注解模式引用类型注入,另一种方式

1、         实现需求

类属性的引用类型注解有2种方式

@resoure(name=’’); @Autowired

@Qualifier(‘...’)  //有时可以省略,是惟一对象时

2、         示例如下

BeanAnn.xml

<!--

下面一行表示开启注解模式,下面的一行配置可以不写,有了scan,会自动开启注解

   <context:annotation-config/>

 -->

   <context:component-scan base-package="iss.spring.ann"/>

   <bean id="i1" class="java.lang.Integer">

      <constructor-arg value="10099" />

   </bean>

   <bean id="s1" class="java.lang.String">

      <constructor-arg value="李晓芳" />

   </bean>

   <bean id="s2" class="java.lang.String">

      <constructor-arg value="ISS17101" />

   </bean>

   <!--

   1993-11-26

    -->

   <bean id="dt" class="java.util.Date">

      <constructor-arg value="93" />

      <constructor-arg value="10" />

      <constructor-arg value="26" />

   </bean>

 

</beans>

@Repository

@Scope("prototype")

public class Student {

   @Resource(name="i1")

   private IntegerstudId;

   @Autowired

   @Qualifier("s1")

   private Stringname;

   @Autowired

   @Qualifier("s2")

   private StringclassId;

   @Autowired  //只有一个类对象时,就不需要qualifier注解

   public Datebirthday;

   public Student() {

      Log.getLog().info("this="+this);

   }

   public Integer getStudId() {

      return studId;

   }

   public String getName() {

      return name;

   }

   public String getClassId() {

      return classId;

   }

  

 

}

 

public class TestSpringAnn {

 

     public static void main(String[] args) {

            // 构建spring容器工具

            ApplicationContext ac=new ClassPathXmlApplicationContext("iss/spring/ann/BeanAnn.xml");

            Log.getLog().info("ok?");

            //通过容器取得类对象

            Student stud=ac.getBean(Student.class);

            Log.getLog().info("stud="+stud);

            Log.getLog().info(

                          ","+stud.getStudId()+

                          ","+stud.getName()+

                          ","+stud.getClassId()+

                          ","+stud.birthday.toLocaleString()

                          );

           

 

     }

 

}

输出如下

iss.spring.ann.Student.<init>(Student.java:36)10-16 11:12:17>

this=iss.spring.ann.Student@3f7944

 

 iss.spring.ann.TestSpringAnn.main(TestSpringAnn.java:26)10-16 11:12:17>

stud=iss.spring.ann.Student@3f7944

 

 iss.spring.ann.TestSpringAnn.main(TestSpringAnn.java:27)10-16 11:12:17>

,10099,李晓芳,ISS17101,1993-11-26 0:00:00

 

二、        关于bean的初始化方法

1、         含意

构建一个类对象时,自动运行类中的某个方法

是spring容器协助调用的

2、         实现方法,多种

1)     当前的sprinng容器Bean.xml文件,指明init-method

2)     实现一个接口,InitializingBean,略

接口的方法就是自动运行的方法

3)     注解方法

 

3、         示例如下

public class Student_Init {

     private Integer studId;

     private String name;

     private String classId;

     @Autowired  //只有一个类对象时,就不需要qualifier注解

     Date birthday;

     public Student_Init() {

            Log.getLog().info("this="+this);

     }

     //下面的方法在BeanInit.xml中定义

     public void myInit(){

            studId=10078;

            name="屈红平";

            classId="ISS1008";

            Log.getLog().info("studId="+studId+

                                   ",name="+name+

                                   ",classId="+classId+

                                   ",birthday="+birthday.toLocaleString()

                                   );

                         

     }

}

BeanInit.xml

<context:annotation-config></context:annotation-config>

   <!--

   下面这行不需要,只需要启动注解即可

   <context:component-scan base-package="iss.spring.init"/>

   1994-2-6

    -->

   <beanid="dt"class="java.util.Date">

      <constructor-argvalue="94"/>

      <constructor-argvalue="1"/>

      <constructor-argvalue="6"/>

   </bean>

   <beanclass="iss.spring.init.Student_Init"init-method="myInit"scope="prototype"/>

 

</beans>

public class TestSpringInit {

 

   public static void main(String[] args) {

      // 构建spring容器工具

      ApplicationContext ac=new ClassPathXmlApplicationContext("/iss/spring/init/BeanAnnInit.xml");

      Log.getLog().info("ok?");

      //通过容器取得类对象

      Student_Init stud=ac.getBean(Student_Init.class);

      Log.getLog().info("stud="+stud);

      Log.getLog().info(

           ","+stud.getStudId()+

           ","+stud.getName()+

           ","+stud.getClassId()+

           ","+stud.birthday.toLocaleString()

           );

     

 

   }

 

}

输出如下

 

 iss.spring.init.Student_Init.<init>(Student_Init.java:35)10-16 11:35:26>

this=iss.spring.init.Student_Init@af5002

 

 iss.spring.init.Student_Init.myInit(Student_Init.java:42)10-16 11:35:26>

studId=10078,name=屈红平,classId=ISS1008,birthday=1994-2-6 0:00:00

 

 iss.spring.init.TestSpringInit.main(TestSpringInit.java:25)10-16 11:35:26>

stud=iss.spring.init.Student_Init@af5002

 

 iss.spring.init.TestSpringInit.main(TestSpringInit.java:26)10-16 11:35:26>

,10078,屈红平,ISS1008,1994-2-6 0:00:00

 


 

三、        关于注解模式初始化方法

1、         实现需求

构建类对象时,运行的初始化方法,是通过注解方法设定的

2、         编程要点

初始化方法注解:@PostConstrutctor

效果等同于 init-method属性

3、         示例如下

@Component

@Scope("prototype")

public class Student_Init2 {

     private Integer studId;

     private String name;

     private String classId;

     @Autowired  //只有一个类对象时,就不需要qualifier注解

     Date birthday;

     public Integer getStudId() {

            return studId;

     }

     public String getName() {

            return name;

     }

     public String getClassId() {

            return classId;

     }

     public Student_Init2() {

            Log.getLog().info("this="+this);

     }

     //下面的方法注解方式定义,随构造函数一起同时运行

     @PostConstruct

     public void myInit(){

            studId=10078;

            name="屈红平";

            classId="ISS1008";

            Log.getLog().info("studId="+studId+

                                   ",name="+name+

                                   ",classId="+classId+

                                   ",birthday="+birthday.toLocaleString()

                                   );

                         

     }

}

BeanAnnInit.xml

   <context:component-scanbase-package="iss.spring.init"/>

   <!--

   下面的日期可以是java.util.Date,也可以是java.sql.Date

    -->

   <beanid="dt"class="java.sql.Date">

      <constructor-argvalue="94"/>

      <constructor-argvalue="1"/>

      <constructor-argvalue="6"/>

   </bean>

   <beanclass="iss.spring.init.Student_Init"init-method="myInit"scope="prototype"/>

 

</beans>

检测类

   public static void main(String[] args) {

      // 构建spring容器工具

      ApplicationContext ac=newClassPathXmlApplicationContext("/iss/spring/init/BeanAnnInit.xml");

      Log.getLog().info("ok?");

      //通过容器取得类对象

      Student_Init2 stud=ac.getBean(Student_Init2.class);

      Log.getLog().info("stud="+stud);

      Log.getLog().info(

           ","+stud.getStudId()+

           ","+stud.getName()+

           ","+stud.getClassId()+

           ","+stud.birthday.toLocaleString()

           );

     

     

   }

 

 

输出如下

iss.spring.init.Student_Init2.<init>(Student_Init2.java:38)10-16 13:42:55>

this=iss.spring.init.Student_Init2@133da0

 

 iss.spring.init.Student_Init2.myInit(Student_Init2.java:46)10-16 13:42:55>

studId=10078,name=屈红平,classId=ISS1008,birthday=1994-2-6 0:00:00

 

 iss.spring.init.TestSpringInit.main(TestSpringInit.java:41)10-16 13:42:55>

stud=iss.spring.init.Student_Init2@133da0

 

 iss.spring.init.TestSpringInit.main(TestSpringInit.java:42)10-16 13:42:55>

,10078,屈红平,ISS1008,1994-2-6 0:00:00

 

 

四、        关于注解类对象标识

1、         实现需求

类似Bean.xml中的id的标识

当一个接口,或抽象类,有多个实现子类时,调用其中一个子类,则此时需要明确标识用其中的哪一个子类

2、         编程要点

1)     写1个接口

2)     写2个实现子类

每个实现子类的注解,加入id标识

@Component(“id标识”)

@Service(“id标识”)

@Repository(“id标识”)

3)     在调用时,得到接口类对象,可以依据id得到其中任何一个子类

3、         示例如下

//下面的类注解,可以写,也可以不写

//@Component

public interface IAdd {

     int add(int a,int b);

}

//@Component("add1")

@Repository(value="add1")

@Scope("prototype")

public class ImplAdd_1 implements IAdd{

     public ImplAdd_1() {

            Log.getLog().info("this="+this);

     }

 

     @Override

     public int add(int a, int b) {

            int c=a+b;

            Log.getLog().info("c="+c+",a="+a+",b="+b);

            return c;

     }

 

}

//@Component("add2")

@Service("add2")

@Scope("prototype")

public class ImplAdd_2 implements IAdd{

   public ImplAdd_2() {

      Log.getLog().info("this="+this);

   }

 

   @Override

   public int add(int a,int b) {

      // TODO Auto-generated method stub

      int c=a+b+1;

      Log.getLog().info("c="+c+",a="+a+",b="+b);

     

      return c;

   }

 

}

 

BeanAnnId.xml

   <context:component-scanbase-package="iss.spring.ann.id"/>

</beans>

检测类

public class TestSpringAnnId {

 

   /**

    * @param args

    */

   public static void main(String[] args) {

      // 构建spring容器工具

      ApplicationContext ac=new ClassPathXmlApplicationContext("/iss/spring/ann/id/BeanAnnId.xml");

      Log.getLog().info("ok?");

//    IAdd add=ac.getBean("add1", IAdd.class);

      IAdd add=ac.getBean("add2", IAdd.class);

      Log.getLog().info("add="+add);

      int n=add.add(2, 3);

      Log.getLog().info("n="+n);

 

   }

 

}

 

输出如下

iss.spring.ann.id.ImplAdd_2.<init>(ImplAdd_2.java:14)10-16 14:02:14>

this=iss.spring.ann.id.ImplAdd_2@16708cc

 

 iss.spring.ann.id.TestSpringAnnId.main(TestSpringAnnId.java:26)10-16 14:02:14>

add=iss.spring.ann.id.ImplAdd_2@16708cc

 

 iss.spring.ann.id.ImplAdd_2.add(ImplAdd_2.java:21)10-16 14:02:14>

c=6,a=2,b=3

 

 iss.spring.ann.id.TestSpringAnnId.main(TestSpringAnnId.java:28)10-16 14:02:14>

n=6

 

 

五、        关于spring+junit检测

1、         实现需求

1)     spring环境,进行junit检测,spring+junit

2)     不需要再构建ApplicationContext

是Junit配置文件注解方式实现

2、         配置要点

1)     spring+junit工作环境

2)     Junit检测类

Ø  有classpath

Ø  无classpath

Ø  file,路径最前面无:/

3、         示例如下

package iss.spring.junit;

 

import iss.spring.init.Student_Init;

 

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.test.context.ContextConfiguration;

import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

 

import qh.Log;

 

/**

 * 作者:刘明

 *2017年10月16日,下午2:08:26

 */

@RunWith(SpringJUnit4ClassRunner.class)

//同一个bean.xml文件注册有下面4种方式,效果相同

//@ContextConfiguration(locations = {"classpath:/iss/spring/init/BeanAnnInit.xml" })  //OK,方法1,OK,表示当前目录运行

@ContextConfiguration(locations = {"/iss/spring/init/BeanAnnInit.xml" })  //方法1,OK,表示当前目录运行

//@ContextConfiguration(locations = {"/qh/spring/ann/BeanAnn.xml"})  //方法2,OK

//@ContextConfiguration(locations = {"file:src/qh/spring/ann/BeanAnn.xml" })  //方法3,OK

//@ContextConfiguration(locations = {"file:src/iss/spring/init/BeanAnnInit.xml" })  //方法4,OK

//@ContextConfiguration(locations = {"file:WebRoot/WEB-INF/BeanAnnInit.xml" })  //方法4,OK

//@ContextConfiguration(locations = {"BeanAnnInit.xml" })  //方法5,OK,检测类与BeanAnn.xml在同一个目录下

 

 

public class TestSpring_Junit {

     @Autowired                                            

     Student_Init stud ;                                     //获取一个bean对象,如若抽象类或者接口,则相当于获得了实现类
                                                                  

   //ApplicationContext ac=new ClassPathXmlApplicationContext("xml");

  // Student_Init stud=ac.getBean(Student_Init.class);

    

     @Test

     public void test1(){

            Log.getLog().info("test1...,stud="+stud);

            Log.getLog().info(

                          ","+stud.getStudId()+

                          ","+stud.getName()+

                          ","+stud.getClassId()+

                          ","+stud.birthday.toLocaleString()

                          );          

     }

     @Test

     public void test2(){

            Log.getLog().info("test2...");

     }

     @Test

     public void test3(){

            Log.getLog().info("test3...");

     }

 

}

输出如下

iss.spring.init.Student_Init.<init>(Student_Init.java:35)10-16 14:23:51>

this=iss.spring.init.Student_Init@180475

 

 iss.spring.init.Student_Init.myInit(Student_Init.java:42)10-16 14:23:51>

studId=10078,name=屈红平,classId=ISS1008,birthday=1994-2-6 0:00:00

 

 iss.spring.junit.TestSpring_Junit.test1(TestSpring_Junit.java:39)10-16 14:23:51>

test1...,stud=iss.spring.init.Student_Init@180475

 

 iss.spring.junit.TestSpring_Junit.test1(TestSpring_Junit.java:40)10-16 14:23:51>

,10078,屈红平,ISS1008,1994-2-6 0:00:00

 

六、        关于代理设计模式

1、         理解生活的代理

Ø  代理商

Ø  代理权力

Ø  代表他人做某个事情

2、         java的代理

一个真正工作任务,由另一个类表现出来,这个任务依然是原有工作完成的,这种方式就是代理设计模式

体现在生活,就是某一本书的盗版

3、         编程要点

1)     写一个任务的接口

2)     写一个任务实现子类,实现任务接口

3)     写一个代理类,要实现任务接口

要代理真正的工作任务实现

4)     写一个检测类

4、         示例如下

public interface IAdd2 {

     int add(int a,int b);

 

}public class ImplAdd implements IAdd2{

   public ImplAdd() {

      Log.getLog().info("this="+this);

   }

 

   @Override

   public int add(int a,int b) {

      int c=a+b;

      Log.getLog().info("c="+c+",a="+a+",b="+b);

      return c;

   }

 

 

 

}

 

public class AddProxy implements IAdd2{

   private IAdd2obj;

   public AddProxy(IAdd2 obj) {

      this.obj=obj;

      Log.getLog().info("this="+this+",proxy obj="+obj);

   }

@Override

   public int add(int a,int b) {

      int n=obj.add(a, b);//代理工作

      Log.getLog().info("n="+n+",a="+a+",b="+b);

      return n;

   }

 

}

 

public class TestProxy {

 

   /**

    * @param args

    */

   public static void main(String[] args) {

      // 构建一个真正的任务

      IAdd2 obj=new ImplAdd();

      Log.getLog().info("obj="+obj);

      //构建代理对象

      IAdd2 proxy=new AddProxy(obj);

      Log.getLog().info("proxy="+proxy);

      int n=proxy.add(2, 3);

      Log.getLog().info("n="+n);

     

 

   }

 

}

 

输出如下

iss.java.pattern.proxy.ImplAdd.<init>(ImplAdd.java:14)10-16 16:02:15>

this=iss.java.pattern.proxy.ImplAdd@26dfcc

 

 iss.java.pattern.proxy.TestProxy.main(TestProxy.java:20)10-16 16:02:15>

obj=iss.java.pattern.proxy.ImplAdd@26dfcc

 

 iss.java.pattern.proxy.AddProxy.<init>(AddProxy.java:17)10-16 16:02:15>

this=iss.java.pattern.proxy.AddProxy@996b65

 

 iss.java.pattern.proxy.TestProxy.main(TestProxy.java:23)10-16 16:02:15>

proxy=iss.java.pattern.proxy.AddProxy@996b65

 

 iss.java.pattern.proxy.ImplAdd.add(ImplAdd.java:20)10-16 16:02:15>

c=5,a=2,b=3

 

 iss.java.pattern.proxy.AddProxy.add(AddProxy.java:22)10-16 16:02:15>

n=5,a=2,b=3

 

 iss.java.pattern.proxy.TestProxy.main(TestProxy.java:25)10-16 16:02:15>

n=5

 

 

七、        关于uml的概念

1、         uml=UnitedModel Language

     统一模型  语言

2、         作用

用各种图的形式表示系统设计,有9种图

1)     用例图,use case

2)     类图

3)     时序图

4)     状态图

5)     活动图

 

八、        关于uml类图

1、         实现需求

用于表示类与类之间的关系,有

继承关系

依赖关系

聚合关系

2、         MyEclipse处理类图

1)     在当前package下,new other,myeclipse,uml2

生成uml工程

2)     生成类图

选中需要生成package或java类

3、         操作如下

 


 

九、        关于继承时的override方法定位问题

1、         实现需求

多态方法的定位

所有动态方法,由距离new 实现子类()最近的方法

2、         分析示例

A、B、C,3个类,add(int a,int b)有3个态

A中动态方法,调用add(int a,int b)则可能是3个态之一

3、         示例如下

public class A {

     int add(int a,int b){

            return a+b;

     }

     void test(){

            int n=add(2,3);

            Log.getLog().info("n="+n);

     }

 

}

public class B extends A{

   @Override

   int add(int a,int b) {

      // TODO Auto-generated method stub

      return a+b+10;

   }

 

}

 

public class C extends B{

   @Override

   int add(int a,int b) {

      // TODO Auto-generated method stub

      return a+b+100;

   }

 

}

public class TestOveridLocation {

 

   /**

    * @param args

    */

   public static void main(String[] args) {

//    A obj=new A();

//    A obj=new B();

      A obj=new C();

      obj.test();

   }

 

}

 

 

十、        关于继承中的覆盖方法定位

1、         原理

父类 obj=new 实现子类();

obj所有动态方法,如有覆盖方法,则必须用等号右边实现子类的覆盖方法,或要调用距离new 类最近的覆盖方法。