Spring学习(二)

Spring学习笔记(9)----让Spring自动扫描和管理Bean
-------------------------------------------------
 
 
 
Java代码 
1.package com.szy.spring.service; 
2
3.import org.springframework.stereotype.Service; 
4
5.import com.szy.spring.dao.PersonDao; 
6.@Service("service"
7.public class UserServiceImpl implements UserService 
8.{ 
9.    private PersonDao personDaoBean; 
10.     
11.    public void show() 
12.    { 
13.        personDaoBean.show(); 
14.    } 
15
16.    public void setPersonDaoBean(PersonDao personDaoBean) 
17.    { 
18.        this.personDaoBean = personDaoBean; 
19.    } 
20.} 
  
 在前面的例子中,都是使用XML的bean定义来使用组件,在大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会使配置文件显得很臃肿,查找和维护起来不方便。Spring2.5为我们引入了组件自动扫描机制,它可以在类路径下寻找标记了@Component@Service@Controller@Repository注解的类,并把这些类纳入到spring容器中管理,它的作用和在xml中使用bean节点配置组件一样。要使用自动扫描机制,我们需要把配置文件如下配置:
  
 
 
Xml代码 
1.<?xml version="1.0" encoding="UTF-8"?> 
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd 
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> 
9.    <context:component-scan base-package="com.szy.spring"></context:component-scan> 
10.</beans> 
  
 其中base-package为需要扫描的包(包括子包)
  
@Service用于标注业务层的组件,@Controller用于标注控制层组件(如struts中的action),@Repository用于标注数据访问组件,即DAO组件,而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。但是在目前的spring版本中,这几个注解的作用是一样的,但是在以后可能会进行区分。
  
  
  
下面把先前的例子修改一下:
  
首先是PersonDaoBean类,修改如下
  
 
 
Java代码 
1.package com.szy.spring.dao; 
2
3.import org.springframework.stereotype.Repository; 
4
5.@Repository 
6.//告诉spring这个类要交给spring管理, 
7.public class PersonDaoBean implements PersonDao 
8.{ 
9.    public void show() 
10.    { 
11.        System.out.println("执行PersonDaoBean中的add()方法"); 
12.    } 
13.} 
  
  
  
然后是UserServiceImpl类
  
 
 
Java代码 
1.package com.szy.spring.service; 
2
3.import org.springframework.stereotype.Service; 
4
5.import com.szy.spring.dao.PersonDao; 
6.@Service 
7.//把这个类交给spring管理,作为服务了。 
8.public class UserServiceImpl implements UserService 
9.{ 
10.    private PersonDao personDaoBean; 
11.     
12.    public void show() 
13.    { 
14.        personDaoBean.show(); 
15.    } 
16
17.    public void setPersonDaoBean(PersonDao personDaoBean) 
18.    { 
19.        this.personDaoBean = personDaoBean; 
20.    } 
21
22.    public PersonDao getPersonDaoBean() 
23.    { 
24.        return personDaoBean; 
25.    } 
26.} 
  
  
  
  
  
 下面我们进行测试,原来的测试代码是userServiceImpl
 
 
 
Java代码 
1.ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); 
2.        UserService service=(UserService)ctx.getBean("userService"); 
3.        service.show(); 
  
  
  
其中userService是我们在配置文件中配置的bean的id。但是如今我们并没有id这个属性,在spring2.5中,默认的id是类的名称,但是开后是小写,也就是userServiceImpl,因此测试代码应修改如下:
  
 
 
Java代码 
1.AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); 
2.        UserService service=(UserService)ctx.getBean("userServiceImpl"); 
3.        System.out.println(service); 
  
  
  
如果我们想自己命名的话,则只需在注解后加上括号,里面写入你希望的名字,如
  
@Service("userService")。
  
  
  
在spring中默认的是之生成一个bean实例,如果我们想每次调用都产生一个实例,则标注需如下配置
  
@Service @Scope("prototype")
  
  
  
在xml中我们还可以配置初始化方法和销毁方法,使用标注后只需如下标注
  
 
 
Java代码 
1.@PostConstruct 
2.    public void init() 
3.    { 
4.        System.out.println("初始化"); 
5.    } 
6.    @PreDestroy 
7.    public void destory() 
8.    { 
9.        System.out.println("销毁"); 
10.    } 
  
  
  
 使用注解后,我们的xml文件变得十分简单,因此建议Spring学习笔记(10)----公共属性的注入配置大家在以后的开发中使用注解。
 
 
 
 
 
 
 
 
 
 
Spring学习笔记(10)----公共属性的注入配置
-------------------------------------------
假设我们定义了四个bean类,其代码分别如下:
  
 
 
Java代码 
1.package com.szy.spring.bean; 
2
3.public class Bean1 { 
4.    private Bean2 bean2; 
5.    private Bean3 bean3; 
6.    private Bean4 bean4; 
7
8.    public Bean2 getBean2() 
9.    { 
10.        return bean2; 
11.    } 
12.    public void setBean2(Bean2 bean2) 
13.    { 
14.        this.bean2 = bean2; 
15.    } 
16.    public Bean3 getBean3() 
17.    { 
18.        return bean3; 
19.    } 
20.    public void setBean3(Bean3 bean3) 
21.    { 
22.        this.bean3 = bean3; 
23.    } 
24.    public Bean4 getBean4() 
25.    { 
26.        return bean4; 
27.    } 
28.    public void setBean4(Bean4 bean4) 
29.    { 
30.        this.bean4 = bean4; 
31.    } 
32.} 
  
  
  
  
  
 
 
Java代码 
1.package com.szy.spring.bean; 
2
3.public class Bean2 
4.{ 
5.    private int id; 
6.    private String name; 
7.    private String password; 
8
9.    public int getId() 
10.    { 
11.        return id; 
12.    } 
13.    public void setId(int id) 
14.    { 
15.        this.id = id; 
16.    } 
17.    public String getName() 
18.    { 
19.        return name; 
20.    } 
21.    public void setName(String name) 
22.    { 
23.        this.name = name; 
24.    } 
25.    public String getPassword() 
26.    { 
27.        return password; 
28.    } 
29.    public void setPassword(String password) 
30.    { 
31.        this.password = password; 
32.    } 
33.} 
  
  
  
  
  
 
 
Java代码 
1.package com.szy.spring.bean; 
2
3.public class Bean3 
4.{ 
5.    private int id; 
6.    private String name; 
7
8.    public int getId() 
9.    { 
10.        return id; 
11.    } 
12.    public void setId(int id) 
13.    { 
14.        this.id = id; 
15.    } 
16.    public String getName() 
17.    { 
18.        return name; 
19.    } 
20.    public void setName(String name) 
21.    { 
22.        this.name = name; 
23.    } 
24.} 
  
  
  
  
  
 
 
Java代码 
1.package com.szy.spring.bean; 
2
3.public class Bean4 
4.{ 
5.    private int age; 
6
7.    public int getAge() 
8.    { 
9.        return age; 
10.    } 
11.    public void setAge(int age) 
12.    { 
13.        this.age = age; 
14.    } 
15.} 
  
  
  
按照正常的思路,我们下面就要给每个类进行属性的注入,配置文件如下设置:
  
 
 
Xml代码 
1.<?xml version="1.0" encoding="UTF-8"?> 
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd 
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> 
9.    <bean id="bean1" class="com.szy.spring.bean.Bean1"
10.        <property name="bean2" ref="bean2"/> 
11.        <property name="bean3"
12.            <ref bean="bean3"/> 
13.        </property>    
14.        <property name="bean4" ref="bean4"/> 
15.    </bean> 
16.     
17.    <bean id="bean2" class="com.szy.spring.bean.Bean2"
18.        <property name="id" value="100"/> 
19.        <property name="name"
20.            <value>kuka</value> 
21.        </property> 
22.        <property name="password" value="123"/> 
23.    </bean> 
24.     
25.    <bean id="bean3" class="com.szy.spring.bean.Bean3"
26.        <property name="id" value="100"/> 
27.        <property name="name" value="kuka"/> 
28.    </bean> 
29.      
30.    <bean id="bean4" class="com.szy.spring.bean.Bean4"
31.        <property name="age" value="22"/> 
32.    </bean> 
33.</beans> 
  
  
  
我们进行测试:
  
 
 
Java代码 
1.@Test 
2.    public void testMethod() throws Exception 
3.    { 
4.        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); 
5.        Bean1 bean1 = (Bean1)ctx.getBean("bean1"); 
6.         
7.        System.out.println("bean1.bean2.id=" + bean1.getBean2().getId()); 
8.        System.out.println("bean1.bean2.name=" + bean1.getBean2().getName()); 
9.        System.out.println("bean1.bean2.password=" + bean1.getBean2().getPassword()); 
10.        System.out.println("bean1.bean3.id=" + bean1.getBean3().getId()); 
11.        System.out.println("bean1.bean3.name=" + bean1.getBean3().getName()); 
12.        System.out.println("bean1.bean4.age=" + bean1.getBean4().getAge()); 
13.    } 
  
  
  
正常输出我们所预期的信息,但是我们观察发现bean2和bean3的部分属性的配置信息是相同的,这仅是两个bean,如果是多个bean的话我们要修改就好修改多处,因此我们可以把这些公共的部分提出出来,进行抽象。这个在Spring中是支持的。我们在建立一个配置文件,命名为:applicationCommon.xml,其内容如下配置
  
 
 
Xml代码 
1.<?xml version="1.0" encoding="UTF-8"?> 
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd 
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> 
9.     <bean id="beanAbstract" abstract="true"
10.        <property name="id" value="100"/> 
11.        <property name="name" value="kuka"/> 
12.   </bean>          
13.    
14.   <bean id="bean2" class="com.szy.spring.bean.Bean2" parent="beanAbstract"
15.            <property name="password" value="123"/> 
16.   </bean>         
17.    
18.   <bean id="bean3" class="com.szy.spring.bean.Bean3" parent="beanAbstract"/> 
19.     
20.</beans> 
  
 beanAbstract就是我们抽象出来的,设置abstract="true"属性后就不需要指定class属性。
  
我们把原来配置文件里的关于bean2和bean3节点注释掉。
  
下面进行测试,在这里要注意由于我们使用了两个配置文件,因此我们在读取是要写两个配置文件名。我们查看ClassPathXmlApplicationContext源文件发现其有个构造函数参数是string数组,因此我们可以把这个配置文件名放在数组里面。此外我们还有另外一种实现方法,两个配置文件一个叫applicationContext.xml,另一个applicationCommon.xml,公共部分是applicationC*.xml,下面我们就可以这样进行测试:
  
 
 
Java代码 
1.@Test 
2.    public void testMethod() throws Exception 
3.    { 
4.        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationC*.xml"); 
5.        Bean1 bean1 = (Bean1)ctx.getBean("bean1"); 
6.         
7.        System.out.println("bean1.bean2.id=" + bean1.getBean2().getId()); 
8.        System.out.println("bean1.bean2.name=" + bean1.getBean2().getName()); 
 
 
9.        System.out.println("bean1.bean2.password=" + bean1.getBean2().getPassword()); 
10.        System.out.println("bean1.bean3.id=" + bean1.getBean3().getId()); 
11.        System.out.println("bean1.bean3.name=" + bean1.getBean3().getName()); 
12.        System.out.println("bean1.bean4.age=" + bean1.getBean4().getAge()); 
13.    } 
  
  
  
如果我们bean2的name属性的值不是kuka,那么我们只需在applicationCommon.xml文件的bean2节点下再添加property属性即可
  
 
 
Xml代码 
1.<property name="name" value="coolszy"/> 
 
 
 
 
 
 
 
 
 
 
 
 
Spring学习笔记(11)----自定义属性编辑器
-------------------------------------------
前面我们所定义的属性都是几本的属性,如果我们定义一个属性是Date类型,例如如下类中:
  
 
 
Java代码 
1.package com.szy.spring.bean; 
2
3.import java.util.Date; 
4
5.public class Bean { 
6.    private Date date; 
7
8.    public Date getDate() 
9.    { 
10.        return date; 
11.    } 
12.    public void setDate(Date date) 
13.    { 
14.        this.date = date; 
15.    } 
16.} 
  
 按照我们以前学过的知识我们需要在配置文件中给该属性注入值
  
 
 
Xml代码 
1.<bean id="bean" class="com.szy.spring.bean.Bean"
2.        <property name="date" value="2009-11-21"/> 
3.    </bean> 
  
 下面我们测试是否成功注入值
  
 
 
Java代码 
1.ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml"); 
2.        Bean bean = (Bean)ctx.getBean("bean"); 
3.        System.out.println(bean.getDate()); 
  
 运行包如下异常
  
 
 
Exception代码 
1.org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bean' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.lang.String] to required type [java.util.Date] for property 'date'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'date': no matching editors or conversion strategy found 
  
 通过错误提示信息我们得知spring不能将string转换成date类型,没有匹配的编辑器或者转换机制。
如果想实现string转换成Date,那么我们自己需要写一个属性编辑器
  
我们新建一个类DatePropertyEditor,这个类要继承PropertyEditorSupport类。
我们需要复写这个类中的setAsText方法,其中text参数就是配置文件中的值。我们的任务就是把text转换成date类型的值。
  
 
 
Java代码 
1.package com.szy.spring.util; 
2
3.import java.beans.PropertyEditorSupport; 
4.import java.text.SimpleDateFormat; 
5.import java.util.Date; 
6
7.public class DatePropertyEditor extends PropertyEditorSupport 
8.{ 
9
10.    @Override 
11.    public void setAsText(String text) throws IllegalArgumentException 
12.    { 
13.        String format="yyyy-MM-dd"
14.        SimpleDateFormat sdf=new SimpleDateFormat(format); 
15.        try 
16.        { 
17.            Date date=sdf.parse(text); 
18.            this.setValue(date);  //把转换后的值传过去 
19.        } catch (Exception e) 
20.        { 
21.            e.printStackTrace(); 
22.        } 
23.    } 
24
25.} 
  
写完编辑器后我们还需要把编辑器注入到spring中。 为了方便管理我们再新建一个配置文件applicationEditor.xml,用来配置属性编辑器
  
 
 
Xml代码 
1.<?xml version="1.0" encoding="UTF-8"?> 
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd 
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> 
9.    <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer"
10.        <!-- 把值注入到CustomEditorConfigurer的 Map类型的customEditors属性--> 
11.        <property name="customEditors"
12.            <map> 
13.                <entry key="java.util.Date"
14.                    <!-- 内部bean只供自己使用 --> 
15.                    <bean class="com.szy.spring.util.DatePropertyEditor"/> 
16.                </entry> 
17.            </map> 
18.        </property> 
19.    </bean> 
20.     
21.</beans> 
  
  
  
下面我们修改下测试代码已读取所有的配置文件
  
 
 
Java代码 
1.ApplicationContext ctx=new ClassPathXmlApplicationContext("application*.xml"); 
2.        Bean bean = (Bean)ctx.getBean("bean"); 
3.        System.out.println(bean.getDate()); 
  
  
  
最后测试,成功输出时间。
  
刚才我们在配置文件中时间的格式是2009-11-21,如果我们修改成2009/11/21呢?
  
运行报错:Unparseable date: "2009/11/21"
  
这时我们需要修改属性编辑器类文件的格式了,很麻烦。既然spring支持注入,那么我们为什么不对格式进行注入呢?
  
修改属性编辑器类:
  
 
 
Java代码 
1.package com.szy.spring.util; 
2
3.import java.beans.PropertyEditorSupport; 
4.import java.text.SimpleDateFormat; 
5.import java.util.Date; 
6
7.public class DatePropertyEditor extends PropertyEditorSupport 
8.{ 
9
10.    private String format; 
11.    @Override 
12.    public void setAsText(String text) throws IllegalArgumentException 
13.    { 
14.         
15.        SimpleDateFormat sdf=new SimpleDateFormat(format); 
16.        try 
17.        { 
18.            Date date=sdf.parse(text); 
19.            this.setValue(date);  //把转换后的值传过去 
20.        } catch (Exception e) 
21.        { 
22.            e.printStackTrace(); 
23.        } 
24.    } 
25.    public String getFormat() 
26.    { 
27.        return format; 
28.    } 
29.    public void setFormat(String format) 
30.    { 
31.        this.format = format; 
32.    } 
33.} 
  
  
  
同时给该类对应的bean添加属性节点
  
 
 
Xml代码 
1.<bean class="com.szy.spring.util.DatePropertyEditor"
2.                        <property name="format" value="yyyy/MM/dd"></property> 
3.                    </bean> 
  
  
  
下次只要我们修改配置文件即可,灵活性很大。
 
 
 
 
 
 
 
 
Spring学习笔记(12)----静态代理模式分析演示
--------------------------------------------
代理模式分为静态代理和动态代理。静态代理就是我们自己定义的代理类,动态代理是程序在运行时生成的代理类。
  
下面演示下静态代理类。首先我们要定义一个接口:
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.public interface UserManager 
4.{ 
5.    public void addUser(String username,String password); 
6.    public void deleteUser(int userId); 
7.    public void modifyUser(int userId,String username,String password); 
8.    public void findUser(int userId); 
9.} 
  
 比较常见的对用户进行增删改查。
  
下面我们常见一个实现类,实现这个接口。
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.public class UserManagerImpl implements UserManager 
4.{ 
5
6.    public void addUser(String username, String password) 
7.    { 
8.        System.out.println("--------UserManagerImpl.addUser()----------"); 
9.    } 
10
11.    public void deleteUser(int userId) 
12.    { 
13.        System.out.println("--------UserManagerImpl.deleteUser()----------"); 
14.    } 
15
16.    public void findUser(int userId) 
17.    { 
18.        System.out.println("--------UserManagerImpl.findUser()----------"); 
19.    } 
20
21.    public void modifyUser(int userId, String username, String password) 
22.    { 
23.        System.out.println("--------UserManagerImpl.modifyUser()----------"); 
24.    } 
25.} 
  
  
  
每个方法仅仅是输出一句话。
  
下面我们定义一个客户端类来调用这些方法。
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.public class Client 
4.{ 
5.    public static void main(String[] args) 
6.    { 
7.        UserManager userManager=new UserManagerImpl(); 
8.        userManager.addUser("coolszy", "kuka"); 
9.    } 
10.} 
  
  
  
运行正常输出我们期望的结果。
  
下面我们需要加入安全性检查,就是调用方法前我们需要进行验证,比较常见的就是权限验证,验证用户是否拥有权限,
  
比较常见的做法就是在UserManagerImpl类中定义一个检查安全性的方法:
  
 
 
Java代码 
1.public void checkSecurity() 
2.    { 
3.        System.out.println("--------UserManagerImpl.checkSecurity()----------"); 
4.    } 
  
 然后在每个方法中都要调用这个方法。但是这样不符合开-闭原则(Open-Closed principle,简称OCP)。因此我们可以使用代理类来实现这个功能。代理模式很显著的特征就是和目标对象的接口一致。在代理类中我们可以控制目标对象。要控制目标对象我们必须有一个目标对象的引用。为了灵活我们可以把目标对象传到方法中,而不是在方法中实例化。同时我们把安全性检查的代码也放到代理类中,在调用每个方法之前调用这个检查方法,通过代理对我们以前的类没有破坏。
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.public class UserManagerImplProxy implements UserManager 
4.{ 
5.    private UserManager userManager; 
6.     
7.    public UserManagerImplProxy(UserManager userManager) 
8.    { 
9.        this.userManager = userManager; 
10.    } 
11.    public void addUser(String username, String password) 
12.    { 
13.        checkSecurity(); 
14.        this.userManager.addUser(username, password); 
15.    } 
16.    public void deleteUser(int userId) 
17.    { 
18.        checkSecurity(); 
19.        this.userManager.deleteUser(userId); 
20.    } 
21.    public String findUser(int userId) 
22.    { 
23.        checkSecurity(); 
24.        return this.userManager.findUser(userId); 
25.    } 
26.    public void modifyUser(int userId, String username, String password) 
27.    { 
28.        checkSecurity(); 
29.        this.userManager.modifyUser(userId, username, password); 
30.    } 
31.    public void checkSecurity() 
32.    { 
33.        System.out.println("--------UserManagerImpl.checkSecurity()----------"); 
34.    } 
35.} 
  
  
  
下面修改客户端类。
  
 
 
Java代码 
1.UserManager userManager=new UserManagerImplProxy(new UserManagerImpl()); 
2.        userManager.addUser("coolszy", "kuka"); 
  
  
  
这样总的来说比较灵活。这个依赖关系是我们自己做的,我们完全可以交给spring处理。
  
按照上面的这种做法有一个缺点,如果接口中方法很多,那么我们实现每一个方法都要添加检查方法checkSecurity(),影响了我们的业务处理。采用静态代理模式我们是没法解决的,这时我们需要使用AOP思想。
  
  
 
 
 
 
Spring学习笔记(13)----动态代理模式分析演示
-----------------------------------------------
上一节演示的是静态代理模式,本节演示的是静态代理模式,既然是动态,那么就不存在UserManagerImplProxy类。
  
使用动态代理我们需要声明一个类SecurityHandler,这个类要实现InvocationHandler接口。
  
在类中定义一个产生动态代理的方法newProxy();同时把我们验证的代码放到这个类中。通过SecurityHandler,当我们调用方法时默认会调用SecurityHandler类invoke方法,我们在这个方法中进行安全性检查,检查通过后在调用真实的方法。需要注意的是目标对象接口中的部分方法是存在返回值的。
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.import java.lang.reflect.InvocationHandler; 
4.import java.lang.reflect.Method; 
5.import java.lang.reflect.Proxy; 
6
7.public class SecurityHandler implements InvocationHandler 
8.{ 
9.    private Object targetObject; 
10.     
11.    public Object newProxy(Object targetObject) 
12.    { 
13.        this.targetObject=targetObject; 
14.        //返回动态代理 
15.        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), 
16.                                      targetObject.getClass().getInterfaces(), 
17.                                      this); 
18.    } 
19.    public Object invoke(Object proxy, Method method, Object[] args) 
20.            throws Throwable 
21.    { 
22.        checkSecurity(); 
23.        Object ret=null
24.        try 
25.        { 
26.            //调用目标对象的真实方法 
27.            ret=method.invoke(this.targetObject, args); 
28.            //ret接受存在的返回值,不存在返回值则为Null 
29.        } catch (Exception e) 
30.        { 
31.            e.printStackTrace(); 
32.        } 
33.        return null
34.    } 
35.    public void checkSecurity() 
36.    { 
37.        System.out.println("--------UserManagerImpl.checkSecurity()----------"); 
38.    } 
39.} 
  
  
  
使用这种方式维护起来相对比较好,我想进行安全性检查就进行,不想就不进行,很方便。
  
下面进行客户端调用
  
 
 
Java代码 
1.package com.szy.spring; 
2
3.public class Client 
4.{ 
5.    public static void main(String[] args) 
6.    { 
7.        SecurityHandler handler=new SecurityHandler(); 
8.        //创建代理对象 
9.        UserManager userManager=(UserManager)handler.newProxy(new UserManagerImpl()); 
10.        userManager.addUser("coolszy", "kuka"); 
11.    } 
12.} 
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值