자바 SE 구현 IoC 상세 설명

7161 단어 JavaSEIoC
JavaSE 의 IoC 구현 방식
자바 SE 는 세 가지 방식 을 제공 하여 IoC 를 실현 할 수 있 습 니 다.각각:
  • Java Beans
  • Java ServiceLoader SPI
  • JNDI(Java Naming and Directory Interface)
  • Java Beans
    java.beans 패키지 의 Introspector 클래스 는 getBeanInfo 방법 을 제공 하여 클래스 정 보 를 얻 을 수 있 습 니 다
    
    BeanInfo bi = Introspector.getBeanInfo(User.class,Object.class);
    위 와 같이 User 클래스 대상 의 BeanInfo 를 얻 을 수 있 습 니 다.그리고 BeanInfo 의 getProperty Descriptors 방법 을 통 해 User 대상 의 모든 속성 과 방법 을 얻 을 수 있 습 니 다.
    메모:자바 beans 에서 set(xxx)방법 에 대해 서 는 writeMethod(),get()방법 에 대해 서 는 readMethod()라 고 통일 적 으로 부 릅 니 다.
    
    Stream.of(bi.getPropertyDescriptors()).forEach(pd->{
            Class<?> propertyType=pd.getPropertyType();
            Method writeMethod=pd.getWriteMethod();
            });
    방법 과 속성 명 을 가 져 온 후 반 사 를 통 해 대응 하 는 값 을 대응 하 는 속성 에 설정 할 수 있 습 니 다.
    
    writeMethod.invoke(name,value);
    우리 가 속성 값 을 주입 할 때,우리 가 주입 하 는 것 은 영원히 문자열 형식 입 니 다.만약 에 주입 해 야 할 속성 이 다른 유형(비 문자열)이 라면,예 를 들 어 User 클래스 중 하 나 는 address 입 니 다.이 address 는 하나의 대상 유형 입 니 다.우 리 는 어떻게 변환 기 를 정의 하고 문자열 형식의 값 을 우리 가 필요 로 하 는 대상 유형 으로 변환 해 야 합 니까?
    우 리 는 AddressEditor 를 설정 해서 이 변환 을 실현 해 야 합 니 다.이 AddressEditor 는 다음 과 같은 두 가지 실현 방식 이 있 습 니 다.
    PropertyEditor 인터페이스 구현
    Property Editor Support 클래스 를 계승 하여 setAsText 방법 을 다시 씁 니 다.
    Property Editor Support 류 는 비교적 편리 한 실현 방식 을 제공 하기 때문에 우 리 는 Property Editor Support 류 를 계승 하 는 방법 으로 유형의 전환 을 실현 합 니 다.
    Address 류 의 디자인 은:
    
    public class Address {
        private String name;
        private Integer num;
        //    get / set / toString
    }
    우리 가 정의 하 는 규칙 은 다음 과 같다.
    입력 한 문자열 은|name 과 num 속성 을 분할 합 니 다.
    예 를 들 어'베 이 커 스 트 리 트|221'이라는 문자열 은'베 이 커 스 트 리 트'를 name,221 을 num 에 부여 하기 때문에 setAsText 방법 을 다시 쓰 는 논 리 는 다음 과 같다.
    
    public class AddressEditor extends PropertyEditorSupport {
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            String[] tokens = text.split("\\|");
            Address address = new Address();
            address.setName(tokens[0]);
            address.setNum(Integer.valueOf(tokens[1]));
            setValue(address);
        }
    }
    마찬가지 로,우 리 는"yyy-MM-dd"와 같은 종류의 문자열 을 날짜 형식 으로 변환 할 수 있 는 DateEditor 를 실현 할 수 있다.
    
    public class DateEditor extends PropertyEditorSupport {
    
        static final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            LocalDate localDate = LocalDate.parse(text, dtf);
            ZoneId zone = ZoneId.systemDefault();
            Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
            setValue(Date.from(instant));
        }
    }
    그리고 자바 beans 의 Property Editor Manager 류 의 register Editor 방법 으로 이 두 개의 Editor 를 등록 해 야 합 니 다.
    
    registerEditor(Address.class,AddressEditor.class);
    registerEditor(Date.class,DateEditor.class);
    마지막 으로 Property Editor Manager 의 findEditor 방법 은 앞에서 얻 은 속성 유형 에 따라 해당 하 는 Editor 를 찾 아 값 을 변환 하여 우리 가 필요 로 하 는 속성 형식의 값 으로 변환 할 수 있 습 니 다.
    
    PropertyEditor editor=findEditor(propertyType);
    if(editor!=null){
        //                    
        editor.setAsText(parameters.get(pd.getName()));
        try{
            writeMethod.invoke(user,editor.getValue());
        }catch(IllegalAccessException|InvocationTargetException e){
            e.printStackTrace();
        }
    }else{
        System.out.println("no editor for:"+pd.getName());
    }
    주 함수 호출 예제
    
    public static void main(String[]args)throws Exception{
        Map<String, String> parameters=new HashMap<String, String>(){
            {
                //   key  Node        
                put("name","    ");
                put("address","   |221");
                put("birthday","1854-01-06");
            }
        };
        User convert=PropertyEditorSample.convert(parameters);
        System.out.println(convert);
    }
    실행 결과
    
    User{name='    ', birthday=Thu Jan 05 23:54:17 CST 1854, address=Address{name='   , 221  }}
    SPI
    정의 지불 인터페이스 PayService
    
    public interface PayService {
        void pay();
    }
    여러 구현 정의:
    
    public class WeixinpayService implements PayService {
        @Override
        public void pay() {
            System.out.println("    ");
        }
    }
    public class AlipayService implements PayService {
        @Override
        public void pay() {
            System.out.println("     ");
        }
    }
    resources 디 렉 터 리 에 META-INF 폴 더 를 만 들 고 META-INF 폴 더 에 services 디 렉 터 리 를 만 드 는 동시에 인터페이스 라 는 전체 경로 이름 을 만 듭 니 다.이 항목 의 경우 PayService 의 전체 경로 이름 은:
    
    org.snippets.ioc.java.spi.PayService
    이 파일 에 구현 클래스 의 전체 경로 이름 을 입력 하 십시오:
    
    org.snippets.ioc.java.spi.AlipayService
    org.snippets.ioc.java.spi.WeixinpayService
    클 라 이언 트 호출:
    
    ServiceLoader<PayService> serviceLoader=ServiceLoader.load(PayService.class);
    
    for(PayService ele:serviceLoader){
        ele.pay();
    }
    그 중에서 ServiceLoader.load 방법 은 모든 설 정 된 PayService 를 실현 할 수 있 습 니 다.
    실행 결과:
    알 리 페 이
    위 챗 페 이 먼 트
    JNDI 방식
    Person 클래스 정의
    
    public class Person implements Remote, Serializable {
    
        private static final long serialVersionUID = 1L;
        private String name;
        private String password;
    
        //   set / get  
    }
    JNDI 클 라 이언 트 구현,Person 초기 화 및 Person 찾기 두 가지 기능 구현
    
    public static void initPerson()throws Exception{
        //  JNDI   JNDI url   。          ,    NoInitialContextException  
        LocateRegistry.createRegistry(3000);
        System.setProperty(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.rmi.registry.RegistryContextFactory");
        System.setProperty(Context.PROVIDER_URL,"rmi://localhost:3000");
    
    
        InitialContext ctx=new InitialContext();
    
        //   person  
        Person p=new Person();
        p.setName("zc");
        p.setPassword("123");
    
        // person     JNDI   ,JNDI     :person。
        ctx.bind("person",p);
        ctx.close();
    }
    
    public static void findPerson()throws Exception{
        //       JNDI   JNDI url        System   ,         
        InitialContext ctx=new InitialContext();
    
        //  lookup  person  
        Person person=(Person)ctx.lookup("person");
    
        //       
        System.out.println(person.toString());
        ctx.close();
    }
    이상 은 JavaSE 가 IoC 를 실현 하 는 상세 한 내용 을 상세 하 게 설명 하 는 것 입 니 다.JavaSE 가 IoC 를 실현 하 는 것 에 관 한 자 료 는 우리 의 다른 관련 글 을 주목 하 세 요!

    좋은 웹페이지 즐겨찾기