반응형
Introduction

BAM Adapter와 BPEL Sensores를 이용하여 주문을 모니터링(dashboard) 해봅시다~



Creating Dashboards in BAM

http://localhost:9001/OracleBAM에 접속합니다.



Architect 버튼을 클릭합니다.



데이터 객체 클릭 후 하위 폴더 생성을 클릭합니다.

Training을 입력 후 폴더 생성 버튼을 클릭합니다.



계속 버튼 클릭 후, 다시 하위 폴더 생성 클릭 후 End2End-105-POProcessing 생성



/Training/End2End-105-POProcessing 에서 데이터 객체 생성을 클릭합니다.



필드 추가를 이용해서 아래와 같이 생성합니다.

Total 필드는 계산됨을 선택하고 공식 편집을 클릭합니다.



Price * Quantity 를 입력합니다.



나머지 필드도 입력 후 데이터 객체 생성 버튼을 클릭합니다.



계속 버튼을 클릭합니다.



레이아웃을 클릭한 상태입니다.



내용 클릭해보면 아직 데이터는 없습니다. -0-



다시 메인 화면에서 Active Studio 버튼을 클릭합니다.



공유 보고서 탭을 클릭합니다.



새 폴더를 클릭합니다.



Training 입력 후 확인 버튼을 클릭합니다.



생성된 Training 폴더를 더블 클릭해서 들어갑니다.



다시 새 폴더 생성을 클릭합니다.



End2End-105-POPRocessing 입력 후 확인 버튼을 클릭합니다.



생성된 폴더를 더블 클릭해서 들어갑니다.



새 보고서 생성 버튼을 클릭합니다.



위 1개 아래 2개의 영역이 있는 보고서를 선택합니다.



제목 부분을 PO Processing Report로 변경합니다.



첫번째는 갱신 정렬 목록(Updating Ordered List)을 선택합니다.



아래쪽에 설정 창이 뜨는데 먼저 데이터 객체를 선택해야합니다. Training을 더블 클릭합니다.



End2End-105-POProcessing을 더블 클릭합니다.



Orders를 선택 후 다음 버튼을 클릭합니다.



데이터 필드를 모두 선택합니다.



다음 버튼을 클릭합니다.



완료 버튼을 클릭합니다.



두번째 영역은 3D 파이 차트(3D Pie Chart)를 선택합니다.



그룹 기준은 Item Type, 차트 값은 Total, 요약 함수는 Sum을 체크 해제하고 Percentage of Total을 체크합니다.

다음 버튼을 클릭합니다.



보기 속성 변경을 클릭합니다.



보기 제목을 Percentage of Total Sales by Item Type으로 변경 후 확인 버튼을 클릭합니다.



3번째는 3D 막대 차트(3D Bar Chart)를 선택합니다.



기룹 기준은 Status, 차트 값은 Order ID, 요약 함수는 Count를 선택 후 다음 버튼을 클릭합니다.



보기 속성 변경 클릭 후 보기 제목을 Purchase Orders by Status로 변경하고 확인을 클릭합니다.



보고서 저장을 클릭합니다.



저장 위치를 공유보고서/Training/Ene2End-105-POProcessing로 지정 후 확인 버튼을 클릭합니다.



확인 버튼을 클릭합니다.





Configure BAM Adapter on WebLogic Server

웹로직 콘솔(http://localhost:7001/console)에 접속하여 배치 목록으로 이동합니다.

OracleBamAdapter를 클릭합니다.



구성 - 아웃바운드 접속 풀 탭으로 이동합니다.

oracle.bam.adapter.adc.RMIConnectionFactory 를 펼치고 eis/bam/rmi를 클릭합니다.



밤 서버 정보를 입력 후 저장 버튼을 클릭합니다.



※ 미리 .../Oracle_SOA1/soa/BAMPlan 폴더를 생성해 놓읍시다!

배치 계획을 미리 생성한 폴더에 맞춰 저장합니다.



저장 되었습니다.



다시 배치 테이블에서 OracleBamAdapter를 선택(체크)하고 갱신 버튼을 클릭합니다.



완료 버튼을 클릭합니다.





Creating a BAM Connection

JDeveloper로 돌아와서 POProcessing 어플리케이션을 엽니다.

Application Resources 네비게이터에서 Connections에서 오른쪽 버튼 클릭 후 New Connection - BAM 을 클릭합니다.



Name은 기본 이름으로 합니다. Next 버튼을 클릭합니다.



BAM Server 정보를 입력합니다.



Test Connectino 버튼을 클릭해서 모두 success 가 나와야 합니다. Finish 버튼을 클릭합니다.



Orders 데이터 객체가 보이네요~





Adding a BAM Service Adapter

BAM Adapter를 추가합니다.



Service Name: OrderBAMAdapter



Browse 버튼을 클릭합니다.



Training/End2End-105-POProcessing/Orders를 선택합니다.



Operation은 Upsert를 선택하고 Enable Batching을 체크합니다. Key로 _Order_ID를 선택합니다.



JNDI Name은 기본 eis/bam/rmi



Finish 버튼을 클릭합ㅎ니다.



route(Mediator)PO와 OrdersBAMAdapter(BAM Adapter)를 연결합니다.



routePO를 더블 클릭합니다.



OrdersBAMAdapter::writetoBAM 으로가는 Transform을 추가합니다.





아래와 같이 연결합니다.





Testing BAM Integration with the BAM Adapter


다시 배치 후 테스트합니다. Mediator에서 BAM으로 간 것을 볼 수 있습니다.



BAM 데이터 객체 내용을 보하나의 데이터가 입력되었습니다.





Adding BAM Sensors to the BPEL Process

approveLargeOrder(BPEL Process)를 편집합니다.



assignCCNumber(Assign) 액티브를 수정합니다.



Copy Operation을 하나 추가합니다.



편집창 오른쪽 상단에 BPEL로 되어있는것을 Monitor로 변경합니다.



assignCCNumber 액티브에서 오른쪽 버튼 클릭 후 Create - Sensor를 클릭합니다.



Name은 PendingApprovalActivitySensor, Evaluation Time은 Completion을 선택합니다.

Activity Variable Sensors에 Variable을 하나 추가합니다.



Variable XPath 오른쪽에 편집 버튼을 클릭합니다.



outputVariable - payload - Order를 선택합니다.



OK를 클릭합니다.



OK 를 클릭합니다.



assignCCNumber 액티브에 센서 아이콘이 생겼습니다.



Structure 팔레트(BPEL 편집창에서만 보입니다)에서 Sensor Actions를 클릭하고 BAM Sensor Action을 클릭합니다.



Action Name은 PendingApprovalSensorAction 입력, Sensor는 PendingApprovalActivitySensor를 선택합니다.

BAM Data Object 오른쪽에 Browse 버튼을 클릭합니다.



Training - End2End-105-POProcessin - Orders를 선택합니다.



_Order_ID키로 추가하고 Map File을 지정 후 Enable Batching을 체크 합니다.

Map File 오른쪽의 + 버튼을 클릭합니다.



아래와 같이 연결합니다. 아래 함수는 current-Datetime()



센서 하나와 그에 해당하는 센서 액티브를 만들었습니다.



이제 callbackClient 액티브에 Sensor를 추가합니다.



Evaluaion Time을 Activation으로 선택하고 Variable는 outputVariable - Orders를 선택합니다.



CallbackActivitySensor에 해당하는 BAM Sensor Action을 만들겠습니다.



설정은 아래와 같습니다.



아래와 같이 2개의 센서와 센서 액션(BAM)이 만들어졌습니다.





Deploying and Running the Composite

모두 배치 후 테스트합니다.



두번째 주문은 Customer ID가 이름이 들어와 있고, approved가 approved로 되어있는것을 확인할 수 있습니다.

assign 센서에서 Pending 상태로 한번 기록되고, callback 센서에서 approved 상태로 업데이트가 됩니다.





5000원 이상의 주문을 하게 되면 Human Task에 의해서 대기 상태에 걸리게 됍니다.

이때는 assign 센서까지는 거쳤는데 아직 callback 센서를 거치지 않아서 상태가 Pending Approval로 입력이 되어있습니다.



휴먼 테스트를 처리 하고 나면



callback 센서에 의해서 상태가 바뀌게 됩니다.



실시간으로 갱신되는 레포트를 보겠습니다.

BAM 메인에서 Active Viewer 버튼을 클릭합니다.



좌측 상단에 보고서 선택 버튼을 클릭합니다.



보고서를 선택합니다.



짜잔~ -_-/ (좀.. 구림...)






반응형
//
반응형
Introduction

SDO를 사용하는 방법을 알아봅시다~



Preparing for the lab

아래 스크립트를 실행하셔야 합니다.


sqlplus soademo/soademo @create_cstomers_table.sql



Creating the ADFBC Service

어플리케이션을 만듭니다.



Application Name: CustomerSDOApp



Project Name: CustomerSDO



Finish 클릭



CustomerSDO 프로젝트에서 마우스 오른쪽 버튼 클릭 후 New... 클릭



Business Tier - ADF Business Components에 Business Components from Tables를 선택합니다.



Connection을 추가합니다.



Connection 정보를 입력합니다.



SQL Flavor와 Type Map은 Oracle로 놔두고 OK

※ 테스트하는 DB(soademo)가 다른 DB이면 바꿔주세요.



CUSTOMERS 테이블을 선택합니다.



Next 버튼을 클릭합니다.



Customers (SOADEMO.CUSTOMERS)를 선택합니다.



Read-Only View Objects 창에서는 그냥 Next 버튼을 클릭합니다.



Name: CustomerSDOAppModule



Finish 버튼을 클릭합니다.



CustomerSDOAppModule을 더블 클릭합니다. Service Interface를 선택합니다.



+ 버튼을 클릭합니다.



Web Service Name: CustomerSDOService



Next 버튼을 클릭합니다.



CustomersView1을 선택합니다.



CustomersView1 선택하면 Basic Operations 탭에 목록이 나오게 됩니다. 하나도 빠짐없이 다 선택합니다. (스크롤 내려서 선택!)



Finish 버튼을 클릭합니다.





Deploying the service

Configureations을 선택 합니다.



CustomerSDOService를 선택 후 Edit 버튼을 클릭합니다.



Datasource Name: jdbc/soademoDatabase. OK 버튼을 클릭합니다.



Defaut Configuration을 CustomerSDOService로 번경합니다.



모두 저장합니다.

CustomerSDO 프로젝트 선택 후 마우슨 오른쪽 버튼 클릭. Project Properties... 클릭합니다.



Java EE Application에서

Java EE Web Application Name: CustomerSDO-webapp, Java EE Web Context Root: customer-app



Deployment에서 Deployment Profile을 추가합니다.



Archive Type을 Business Components Service Interface로 선택하고 Name은 customerSDOProfiles로 입력합니다.



추가된 customerSDOProfile을 펼치고, MiddelTier (EJB JAR File) 선택 후 Edit 버튼을 클릭합니다.



EAR File을 customer-app.ear 로 변경하고, Enterprise Application Name을 CustomerSDO로 변경합니다.

OK 버튼을 클릭합니다.



OK 버튼을 클릭합니다.



Deploy 합니다.



http://localhost:8001/customer-app/CustomerSDOService로 접속합니다.

아래와 같은 화면이 나오는데, 작업에서 getCustomersView1 선택 후 customerId에 1111을 입력하고 호출 버튼을 눌러봅시다.



결과가 나옵니다. 형식이 지정된 XML을 클릭하면 좀 더 이쁘게 볼 수 있습니다.



이 웹서비스를 POProcessing에서 사용해봅시다.



Using the SDO in POProcessing Composite

POProcessing Composite 편집 화면에서 Web Service를 추가합니다.



전에 추가한 웹서비스의 WSDL URL을 알기 위해서는 서비스 설명을 참조하십시오.를 클릭하거나 뒤에 ?wsdl 을 붙이면 됩니다.



위 URL을 복사합니다.



WSDL URL에 붙여넣기 합니다. 붙여넣기 후 포커스를 다른 곳으로 이동시키면 자동으로 정보를 읽어들입니다.



approveLargeOrder(BPEL Process)를 수정합니다.



Structure 팔레트에서 Variable를 추가합니다.



Name: CustomerInfoEV. Element 선택 후 Browse 버튼을 클릭합니다.



아래와 같이 CustomerSDOService.wsdl에 있는 스키마를 선택합니다.



Entity Variable 채크 후 Partner Link 오른쪽의 Browse 버튼을 클릭합니다.



CustomerSDOService를 선택합니다.



OK 버튼을 클릭합니다.



receiveInput 액티브 아래에 Bind Entity 액티브를 추가합니다.



이름을 BindCustomerId로 변경 후 편집합니다.(더블 클릭)



Entity Variable 오른쪽의 Browse 버튼을 클릭합니다.



CustomerInfoEV를 선택합니다.



Unique Key를 추가합니다.



KeyLocal Part 오른쪽 Browse 버튼을 클릭합니다.



CustomerInfoEV - customersViewSDO - CustomerId를 선택합니다.



Key Value 오른쪽에 Express Builder 버튼을 클릭합니다.



inputVariable - payload - Order - customerId를 선택합니다.



OK 버튼을 클릭합니다.



OK 버튼을 클릭합니다.



Assign 액티브를 BindCustomerId 아래에 추가합니다.



Name: AssignCustomerName. 아래와 같이 Copy Operation을 추가합니다.



Human Task 가 속해있는 Switch 액티브 바로 아래에 Assign 액티브를 추가합니다.



Name: AssignOrderInfo. 아래와 같이 2개의 Copy Operation을 추가합니다.





POProcessing composite 배치 후, 1000~5000 가격의 데이터를 테스트해봅시다.


테스트 후 흐름 추적에서 callbackClient 부분을 보면 고객의 이름이 나온 것을 확인할수 있습니다.



실제 db에서 customers 테이블을 select 해보면 주문정보가 갱신되어있습니다.







반응형
//

Subversion

Posted at 2010. 8. 16. 00:55 | Posted in Server/Ubuntu
반응형

Subversion 설치

# sudo apt-get install subversion

svn 루트 디렉토리 생성

# mkdir /var/svn
# cd /var/svn

저장소 생성

# svnadmin create --fs-type fsfs test

권한 설정

# sudo chgrp -R svn test
# sudo chmod -R g+w test

※ 출처: http://mtsparrow.blogspot.com/2008/12/ubuntu-svn.html
반응형

'Server > Ubuntu' 카테고리의 다른 글

Disable automatic updates kernel on Ubuntu  (2) 2017.12.20
Installation Redmine on Ubuntu  (0) 2014.03.26
Installation Maven 3 on Ubuntu  (0) 2014.03.25
Using Xmanager to Ubuntu 10.10  (0) 2011.04.13
Openfire  (0) 2010.05.25
Webmin  (0) 2009.11.18
Squirrelmail  (0) 2009.11.12
SparkWeb  (0) 2009.11.12
Cacti  (0) 2009.11.12
Apache + SSL  (0) 2009.11.12
//
반응형
Introduction

Event Driven Network(EDN)으로 인스턴스를 싱행하는 방법을 알아보겠습니다.

JMS, AQ 같은것들로도 된다는거 같네용 ㄷㄷ



Defining the event

Poprocess Composite 편집 화면에서 Event Definition Creation 아이콘을 클릭합니다.



EDL File Name은 POEvents를 입력하고, Events 부분에서 Add an Event 버튼을 클릭합니다.



Element는 po.xsd - PuchaseOrder를 선택합니다.

Name은 NewPO를 입력하고 OK를 클릭합니다.



Events에 NewPO가 추가된 것을 확인하고 OK를 클릭합니다.



자동으로 열리는 POEvents.edl 창은 닫습니다.



다시 POProcessing Composite에 Mediator를 추가합니다.



Name은 receiveNewPO를 입력하고, Template은 Subscribe to Events를 선택합니다.

Subscribe to Events를 선택하게 되면 이떤 이벤트를 읽어(구독)들일건지 설정하는 화면으로 바뀝니다.

+ 버튼을 클릭합니다.



NewPO를 선택합니다. (이미 선택되어져 있습니다.



OK를 클릭합니다.



receiveNewPO(Mediator)와 routePO(Mediator)를 연결합니다.



receiveNewPO를 더블 클릭하여 편집합니다.



Transform Using을 만듭니다.









Deploying and testing

아래 파일을 다운로드 받아서 편집합니다. (soa suite 11.1.1.2.0에 클래스패스를 변경한 파일입니다.)



lab 에 나온대로 11.1.1.1.x 쓰시면 아래 파일을 받아주세요



DB_USERID, DB_PASSWD, DB_CONN, ORACLE_HOME 값을 자신에 맞게 변경합니다.

※ 여기서 DB 정보는 RCU를 이용해서 만들었던 DB 정보 입니다.

명령 프롬프트 창에서 ORACLE_HOME 환경변수를 자신의 설치폴더에 맞게 설정합니다.

> set ORACLE_HOME=C:\Oracle\Middleware\Oracle_SOA1

만약 Java 가 실행이 안되다면 설치하시고 java.exe 가 실행이 되게 설정해주세요~

이벤트를 실행해봅시다!


> publish.cmd new_po_event.xml

성공적으로 실행 되었다면 아래와 같은 메시지가 나옵니다.

Creating datasource...
Creating BusinessEventConnectionFactory...
Creating connection...
2010. 8. 12 오후 4:10:47 oracle.integration.platform.blocks.event.jms.ContextHelper lookupContextProviderClass
정보: Context provider properties file not found
Creating Business Event...
Sending event:
<business-event xmlns:ns="http://schemas.oracle.com/events/edl/POEvents" xmlns="http://oracle.com/fabric/businessEvent">
   <name>ns:NewPO</name>
   <id>e4196227-806c-4680-a6b4-6f8df931b3f3</id>
   <content>
      <PurchaseOrder xmlns="http://xmlns.oracle.com/ns/order">
         <CustID>1111</CustID>
         <ID>33412</ID>
         <productName>Sony Bluray DVD Player</productName>
         <itemType>Electronics</itemType>
         <price>350</price>
         <quantity>5</quantity>
         <status>Initial</status>
         <ccType>Mastercard</ccType>
         <ccNumber>1234-1234-1234-1234</ccNumber>
      </PurchaseOrder>
   </content>
</business-event>
Done.

이제 EM에 들어가서 POProcessing 을 확인해보면 인스턴스가 생성된 것을 확인 할 수 있습니다.

흐름 추적을 해보면 receiveNewPO Service에 의해서 실행이 된 것을 확인 할 수 있습니다.



※ lab을 잘 따라 했다면 여기서 성공하지 않고 에러가 나서 복구 대기중일 겁니다.

이유는 Chapter E 에서 했던 보안 정책 때문에 그런데 비활성화하고 하면 잘 됩니다.

또는 그냥 복구 하면 바로 잘 됩니다. 왜 그런지는 저도 잘 -_-;;;







반응형
//

Chapter E - Enforcing Policies

Posted at 2010. 8. 12. 14:15 | Posted in Oracle Solution/PO Processing
반응형
Introduce

서비스에 보안정책을 정하는 방법을 알아봅시다~

- How to attach a policy
- How to secure invocation of a composite using web services security usernametoken(userid/password).
- How to propagate identiry across a multi-composite to an invoked service using SAML[각주:1].
- Communicate signed and encrypted messages.



Policy attachment in console

EM에서 POProcessing Composite을 클릭합니다.



정책 탭을 클릭합니다.



첨부 대상/분리 위치 버튼을 클릭 후 receivePO를 클릭합니다.



사용 가능한 정책 목록에서 "was_username_token_service_policy"를 클릭 후 첨부 버튼을 클릭합니다.



첨부된 정책 목록 확인 후 확인 버튼을 클릭합니다.



이번에는 getCreditCardStatus에 정책을 첨부합니다.



"oracle/wss11_saml_token_with_message_protection_client_policy"를 첨부합니다.



2가지 정책이 첨부 되었습니다.



validationForCC Composite의 getStatusByCC에도 정책을 첨부합니다.



"oracle/wss11_saml_token_with_message_protection_service_policy"를 첨부 합니다.



1가지의 정책이 첨부되었습니다.



POProcessing을 테스트합니다.

테스트를 할때 보안 분에서 "WSS 사용자 이름 토큰"을 선택하고 사용자 이름과, 비밀번호를 입력해야 니다.



입력하지 않거나 틀리면 아래와 같은 에러가 납니다.





A quick look at policy management

EM 왼쪽 메뉴에서 "WebLogic 도메인 - domain1(자기도메인)"에서 오른쪽 버튼 클릭 후 "웹서비스 - 정책"을 클릭합니다.



적용된 정책 목록이 나옵니다.





Policy attachment in JDeveloper

JDeveloper에서 정책을 적요시키는 법을 알아봅시다.

POProcessing에서 receivePO(Web Service)에서 오른쪽 버튼 클릭 후 Configure WS Policies...를 클릭합니다.



Security 부분에서 정책을 추가합니다.



OK를 클릭하면 receivePO(Web Service)에 자물쇠 아이콘에 생긴 것을 확인할 수 있습니다.



getGreditCardStatus(Web Service)와 validationForCC의 getStatusByCC(Web Service)에도 정책을 적용합니다.





getStatusByCC











  1. http://jangsunjin.tistory.com/33 [본문으로]
반응형
//

Chapter D - Fault Handling

Posted at 2010. 8. 12. 13:27 | Posted in Oracle Solution/PO Processing
반응형
Introduction

에러가 발생했을때 처리하는 법을 알아보겠습니다.



Test service unavailability

원격 에러(remote fault) 에 대한 에러 처리 정책을 정의하는 법을 알아봅시다.

먼저 validationForCC 웹서비스를 잠시 내려봅시다.

JDeveloper의 Application Server Navigator에서 validationForCC(Composite)를 내릴 수 있습니다.





※ Application Server Navigator가 안보인다면 View 메뉴에 있습니다.



※ EM(Enterprise Manager)에서도 내릴 수 있습니다.



이제 POProcessing를 테스트 합시다.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body xmlns:ns1="http://xmlns.oracle.com/ns/order">
        <ns1:PurchaseOrder>
            <ns1:CustID>1111</ns1:CustID>
            <ns1:ID>2222</ns1:ID>
            <ns1:productName>iPod shuffle</ns1:productName>
            <ns1:itemType>Electronics</ns1:itemType>
            <ns1:price>145</ns1:price>
            <ns1:quantity>30</ns1:quantity>
            <ns1:status>Initial</ns1:status>
            <ns1:ccType>Mastercard</ns1:ccType>
            <ns1:ccNumber>1234-1234-1234-1234</ns1:ccNumber>
        </ns1:PurchaseOrder>
    </soap:Body>
</soap:Envelope>

메시지 흐름 추적 실행을 해보면 에러가 발생했습니다.



getStatusByCC 웹서비스를 호출해야 하는데 웹서비스가 꺼져있어서 나는 에러 입니다.



remoteFault를 확인할 수 있습니다.





Add policy-based fault handler to do manual recovery

사용자 복구를 위한 기본 정의를 추가해봅시다.

아래 두 파일을 POProcessing 프로젝트 폴더에 복사합니다.

 



JDeveloper의 Application Navigator에서 새로고침을 누르면 복사된 파일이 나타납니다.



fault-policies.xml 파일은 에러에 따른 처리를 정의하는 파일이고, fault-bindings.xml 파일은 이 정의를 적용시키는 역할을 합니다.

fault-policies.xml 파일을 열어서 편집합니다.

Step D.2.2.2 주석 바로 아래에 아래의 내용을 추가합니다.

      <!-- Step D.2.2.2: Add your fault handler for remote fault here: -->
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:remoteFault">
        <condition>
            <action ref="ora-human-intervention" />
        </condition>
      </faultName>

모두 저장 후 배치 합니다.

EM 에서 다시 테스트 후 메시지 흐름 추적 실행을 해보면 getStatusByCC는 에러가 나있고, approveLargeOrder(BPEL Process)는 실행 중인 것을 확인할 수 있습니다.

그리고 오류 메시지 부분에 복구라는 부분이 생겼습니다.



감사 추적을 보면 아래와 같은 부분이 나옵니다.



BPEL Process의 흐름을 보면 invokeCCStatusService 액티브에서 노란색 오로라를 뿜고 있습니다.

이 Invoke 부분에서 remote fault이 발생하여 사용자가 수동으로 처리를 해주기를 기다리고 있는 것입니다.



※ 여기서도 확인할 수 있습니다.



이제 validationForCC composite를 다시 살립시다.



위의 상태에서 "복구"를 누르거나 BPEL Process 추적 창에서 복구탭을 누르거나(방법은 좀 있는듯...) 해서 복구 탭으로 이동합니다.

에러 메시지 선택 후 복구 버튼을 클릭합니다.



예 클릭



정상적으로 에러가 없이 됐으면 아래와 같이 오류 메시지 목록에 아무것도 없습니다.



흐름 추적을 보변 2번째 복구(1번은 처음 실행시에 난 에러)에서 처리가 되어서 정상 처리가 끝까지 된 것을 확인할 수 있습니다.





Handle faults in BPEL

먼저 Database에서 작업을 하나 해줘야합니다. soademo/soademo로 들어가서 create_validate_cc.sql 스크립트를 실행해주세요.



CreditCardValidation Application - validationForCC Project - composite.xml 파일을 열어 편집합니다.

Database Adapter를 추가합니다.



Service name: validateCC



JNDI Name: eis/DB/soademoDatabase



Call a Stored Procedure or Function을 선택합니다.



Browse 버튼을 클릭합니다.



VALIDATECC를 선택합니다.



선택된 프로시저 확인 후 Next 클릭



Next



Finish



RouteReques(Mediator)와 validateCC(Database Adapter)를 연결합니다.



RouteReques(Mediator)를 더블 클릭하여 편집합니다.

getCreditValidation으로 가는 조건을 입력합니다.



not(starts-with($in.request/inp1:creditcardStatusRequest/inp1:CCNumber, '2'))

카드번호 맨 앞자리가 '2'로 시작하지 않는 조건입니다.



validateCC로 가는 조건도 입력합니다.

starts-with($in.request/inp1:creditcardStatusRequest/inp1:CCNumber, '2')

카드번호 맨 앞자리가 '2'로 시작하는 조건입니다.

validateCC로 가는 Transform 맵핑을 설정합니다.







validateCC에서 리턴받는 Transform 맵핑을 설정합니다.







모두 저장후 배치 합니다.

카드번호가 2로 시작하는 데이터를 입력합니다.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body xmlns:ns1="http://xmlns.oracle.com/ns/order">
        <ns1:PurchaseOrder>
            <ns1:CustID>1111</ns1:CustID>
            <ns1:ID>2222</ns1:ID>
            <ns1:productName>iPod shuffle</ns1:productName>
            <ns1:itemType>Electronics</ns1:itemType>
            <ns1:price>145</ns1:price>
            <ns1:quantity>30</ns1:quantity>
            <ns1:status>Initial</ns1:status>
            <ns1:ccType>Mastercard</ns1:ccType>
            <ns1:ccNumber>2234-1234-1234-1234</ns1:ccNumber>
        </ns1:PurchaseOrder>
    </soap:Body>
</soap:Envelope>

binding fault 에러가 발생했습니다.



BPEL 내에서 binding fault 에러를 제어 해봅시다.

approverLargeOrder(BPEL Process)를 편집합니다.



assignCCNumber(Assign) 액티브와 invokeCCStatusService(Invoke) 액티브 사이에 Scope 액티브를 추가합니다.



이름 부분을 더블 클릭 후 checkCC로 변경합니다.



Scope 액티브를 펼칩니다.



invokeCCStatusService(Invoke) 액티브를 Scope 액티브 안으로 넣습니다.



Scope 내의 아이콘중에 Add Catch Branch 아이콘을 클릭합니다.



추가된 Catch Branch를 펼칩니다.



Catch 아이콘을 더블 클릭합니다.



Browse Faults 버튼을 클릭합니다.



System Faults > bindingFault 을 선택합니다.



Fault Variable을 자동 생성합니다.



OK를 클릭합니다.



OK를 클릭합니다.



catch 영역 안에 Switch 액티브를 추가합니다.



<case> 의 조건을 입력합니다.



<case> 영역에 Assign 액티브를 추가합니다.



이름을 Assign_UNKNOWNCC로 변경 후 아이콘을 더블 클릭합니다.



From은 'UNKNOWN CC' 입력, To는 invokeCCStatusService_execute_OutputVariable - reply - creditcardStatus를 선택합니다.



<otherwise> 영역에 Throw 액티브를 추가합니다.



이름을 Throw_Binding_Fault로 변경 후 아이콘을 더블 클릭합니다.



Fault QName은 System Faults > bindingFault 선택 후 Fault Variable 오른쪽에 Browse Fault Variables.. 버튼을 클릭합니다.



catch 설정할 때 만들었던 FaultVar를 선택합니다.



OK 클릭



fault-policies.xml 파일을 열어 아래 내용을 추가합니다. (Step D.2.4.20 주석 아래에)

      <!-- Step D.2.4.20: Add your fault handler for binding fault here: -->
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:bindingFault">
        <condition>
          <!-- Let the component handle this specific binding fault -->
          <test>$fault.code="20001"</test>
          <action ref="ora-rethrow-fault" />
        </condition>
      </faultName>

다시 카드번호가 '2'로 시작하는 데이터로 테스트 해보겠습니다.

getStatusByCC 서비스에서 에러는 났지만 approveLargeOrder(BPEL Process)는 정상적으로 완료 되었습니다.



감사 추적을 살펴보면 invokeCCStatusService 액티브에서 오류가 발생했고 catch 영역에서 에러를 처리했습니다.



BPEL에서 Scope는 Java의 try catch 역할도 합니다.



Using A Custom Java Fault Handler

이번에는 사용자가 직접 Java로 작성한 에러 처리를 적용해보겠습니다.

※ 에러처리에 사용할 예제 java 소스(jar)가 웹로직 서버 도메인의 lib 폴더에 있어야 합니다. 서버 실행중에 적용했다면 재시작!!

그리고 C:\po\log 폴더(웹로직 서버가 구동중인 컴퓨터입니다!!! 주의!)가 존재야 합니다.




fault-policies.xml 파일을 아래와 같이 수정합니다.

      <!-- Step D.2.4.20: Add your fault handler for binding fault here: -->
      <faultName xmlns:bpelx="http://schemas.oracle.com/bpel/extension" name="bpelx:bindingFault">
        <condition>
          <!-- Let the component handle this specific binding fault -->
          <test>$fault.code="20001"</test>
          <!-- <action ref="ora-rethrow-fault" /> -->
          <action ref="my-java-handler" />
        </condition>
      </faultName>

모두 저장 후 다시 배치. 카드 번호가 '2'로 시작하는 데이터로 테스트 해보겠습니다.

잘 처리 되었습니다.



soa console 에는 아래와 같이 출력됩니다.

MyFaultHanlder: Handle Fault
MyFaultHanlder: Properties
MyFaultHanlder: =================================================================
MyFaultHanlder: logFileName = myfaulthandler.log
MyFaultHanlder: logFileDir = c:\po\log

c:\po\log\myfaulthandler.log 파일을 열어보면 아래와 같습니다.

Fault Details
===============================================================
Fault Type ................ bpel
Poilcy ID ................. POProcessingFaults
Faulted Partner Link ...... getGreditCardStatus
Port Type ................. {http://oracle.com/sca/soapservice/CreditCardValidation/validationForCC/getStatusByCC}getGreditCardStatus



Handle Mediator Faults

Mediator에서 나는 에러를 처리해봅시다.

fault-policies,xml 을 아래와 같이 편집합니다. (Step D.2.6.1 주석 아래에 추가)

      <!-- Step D.2.6.1: Add your fault handler for mediator faults here: -->
      <faultName xmlns:medns="http://schemas.oracle.com/mediator/faults" name="medns:mediatorFault">
        <condition>
          <action ref="my-mediator-fault-handler" />
        </condition>
      </faultName>

Action을 하나 더 추가합니다. (Step D.2.6.2 주석 아래 추가)

      <!-- Step D.2.6.2: Add the Action definition for handling mediator fauls using custom java here:-->
      <Action id="my-mediator-fault-handler">
        <javaAction className="soatraining.faulthandling.MyFaultHandler"
            defaultAction="ora-terminate" propertySet="myMediatorProps">
            <returnValue value="OK" ref="ora-human-intervention" />
        </javaAction>
      </Action>

새로운 JavaAction에 사용되는 프로퍼티를 세팅합니다. (Step D.2.6.3 주석 아래 추가)

      <!-- Step D.2.6.3?: Add new property set for MyFaultHandler for logging Mediator faults here:-->
      <propertySet name="myMediatorProps">
        <property name="logFileName">mediator-faults.log</property>
        <property name="logFileDir">c:\po\log</property>
      </propertySet>

routePO(Mediator)를 수정합니다.



WriteApprovalResults 로 가는 라우팅을 병렬(Parallel)로 변경합니다.



Yes를 클릭합니다.



모두 저장 후 재배치합니다.

에러를 내기 위헤서 파일이 저장되는 폴더(C:\Temp)를 읽기 전용(쓰기 불가능)으로 만들겠습니다.

윈도우(Windows)의 경우
  - 읽기전용 설정
    > attrib +r c:\temp
  - 읽기전용 해제
    > attrib -r c:\temp
리눅스(Linux)의 경우
  - 읽기전용 설정
    $ chmod -w /temp
  - 읽기전용 해제
    $ chmod +w /temp 

이제 EM(Enterprise Manager)에서 테스트를 해봅시다.

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body xmlns:ns1="http://xmlns.oracle.com/ns/order">
        <ns1:PurchaseOrder>
            <ns1:CustID>1111</ns1:CustID>
            <ns1:ID>2121</ns1:ID>
            <ns1:productName>Bluetooth Headset</ns1:productName>
            <ns1:itemType>Electronics</ns1:itemType>
            <ns1:price>49.99</ns1:price>
            <ns1:quantity>1</ns1:quantity>
            <ns1:status>Initial</ns1:status>
            <ns1:ccType>Mastercard</ns1:ccType>
            <ns1:ccNumber>8765-8765-8765-8765</ns1:ccNumber>
        </ns1:PurchaseOrder>
    </soap:Body>
</soap:Envelope>

메시지 흐름 추적을 보면 에러가 났습니다.



감사 추적을 보면 WriteApprovalResults.Write 부분에서 에러가 난것을 볼 수 있습니다.



C:\Temp 폴더의 읽기 전용을 해제 한뒤, 복구를 해봅시다.



예 클릭



복구 작업이 성공적으로 완료되었습니다.



다시 메시지 흐름 추적을 보면 재시도한 흔적(?)을 확인할 수 있습니다.







반응형
//
반응형
Eclipse + Apatana 를 이용하여 jQuery Code Assist를 사용하다가, Ext JS도 지원하길래 써봤는데 별로 기능이 쉬원치 않더군요...

그래서 ExtJS를 지원하는 다른 것을 찾았습니다~

http://www.spket.com/

Ext JS 외에 다른 것(jQuery, Flex, 등)도 이것저것 지원되네요.


Installation

Eclipse Galileo 에서 설치하였습니다.

일단 Ext JS 라이브러리가 어딘가에 있어야 합니다.


Help - Install New Software...



Add 클릭



http://www.spket.com/update/ 등록

Spket IDE 선택



Next



Finish



플러그인 설치 후 이클립스를 재시작 합니다.

WIndow - Preferences



Spket - JavaScript Profiles

New... 클릭



Name 입력



추가한 이름(ExtJS) 선택 후 Add Library 클릭



Library를 ExtJS로 선택합니다.



추가된 라이브러리 선택 후 Add FIle 클릭



Ext JS 라이브러리 파일들 중에 ext.jsb2 파일을 선택합니다.



잘 등록 되었습니다.



ExtJS를 선택 하고 Default를 클릭하여 기본 프로파일이 되게 하니다.



General - Editors - File Associations 에서 *.js 파일의 편집기를 Spket JavaScript Editor로 설정합니다.



이제 js 파일을 작성해봅시다.

만족할 만큼 Code Assist 기능이 작동 하는군요 ㅎㅎ



API 문서 번갈아서 볼 수고는 좀 덜었네요 ㅎㅎ



반응형
//
반응형
출처 : http://onjava.com/lpt/a/6443



스프링 XML Configuration을 위한 12가지 최선의 실천사항들

by Jason Zhicheng Li
01/25/2006

Spring is a powerful Java application framework, used in a wide range of Java applications. It provides enterprise services to Plain Old Java Objects (POJOs). Spring uses dependency injection to achieve simplification and increase testability.property name="shippedBy" value="lizjason Spring beans, dependencies, and the services needed by beans are specified in configuration files, which are typically in an XML format. The XML configuration files, however, are verbose and unwieldy. They can become hard to read and manage when you are working on a large project where many Spring beans are defined.

스프링은 Java 애플리케이션의 많은 범위에서 사용하고 있는 강력한 Java 애플리케이션 프레임워크입니다. 이것은 POJO(Plan Old Java Objects)에 엔터프라이즈 서비스의 힘을 제공합니다. 스프링은 간결함과 테스트 용이성을 이루기 위해 의존성 주입(dependency injection)을 이용합니다. 스프링 빈들과 의존성 그리고 빈들이 필요한 서비스들은 configuration 파일들에 설정하는데 일반적으로 XML 형식으로 되어 있습니다. 어쨌거나 이 XML configuration 파일들은 장황하고 다루기 쉽지 않습니다. 큰 프로젝트에서 스프링 빈을 많이 정의할 경우 이 configuration은 읽기도 어렵고 관리하기도 어려워집니다.

In this article, I will show you 12 best practices for Spring XML configurations. Some of them are more necessary practices than best practices. Note that other factors, such as domain model design, can impact the XML configuration, but this article focuses on the XML configuration's readability and manageability.

이 기사에서 스프링 XML configuration에 대한 12가지 최선의 실천사항들을 소개할 것입니다.  그 중 일부는 최선의 실천사항이라기 보다는 필수 실천사항들입니다. 도메인 모델 설계같은 다른 요소의 영향도 고려해야 하지만 이 기사에서는 configuration의 가독성(readability)과 관리편의성(manageablitity)에 초점을 두었습니다.


1. Avoid using autowiring
Spring can autowire dependencies through introspection of the bean classes so that you do not have to explicitly specify the bean properties or constructor arguments. Bean properties can be autowired either by property names or matching types. Constructor arguments can be autowired by matching types. You can even specify the autodetect autowiring mode, which lets Spring choose an appropriate mechanism. As an example, consider the following:

스프링은 빈의 introspection을 통해 의존관계를 자동으로 묶을(autowirie) 수 있어 명시적으로 빈의 프로퍼티나 생성자 아규먼트를 지정하지 않아도 됩니다. 프로퍼티 이름이나 타입 매칭으로 빈의 프로퍼티를 자동 설정할 수 있습니다. 타입 패칭으로 생성자의 아규먼트를 자동 설정할 수 있습니다. 또한 자동탐지를 autowiring 모드로 지정하여 스프링이 적절한 메커니즘을 선택하게 할 수 있습니다. 다음 예제를 보십시오.

<bean id="orderService" class="com.lizjason.spring.OrderService" autowire="byName"/>

The property names of the OrderService class are used to match a bean instance in the container. Autowiring can potentially save some typing and reduce clutter. However, you should not use it in real-world projects because it sacrifices the explicitness and maintainability of the configurations. Many tutorials and presentations tout autowiring as a cool feature in Spring without mentioning this implication. In my opinion, like object-pooling in Spring, it is more a marketing feature. It seems like a good idea to make the XML configuration file smaller, but this will actually increase the complexity down the road, especially when you are working on a large project where many beans are defined. Spring allows you mix autowiring and explicit wiring, but the inconsistency will make the XML configurations even more confusing.

컨테이너에서 OrderService 클래스의 프로퍼티 이름으로 빈 인스턴스를 매치하도록 사용하고 있습니다. Autowiring은 어쩌면 타이핑하는 수고를 줄이고 난잡함을 줄일 수 있습니다.  그러나 이것은 configuration의 명확성과 유지보수성을 희생하기에 실제 프로젝트에서 사용하면 안됩니다. 많은 튜토리얼과 프리젠테이션에서 이러한 숨겨진 영향을 언급하지 않고 스프링의 쿨한 특징으로 적극 추천하고 있습니다. 사견으로 스프링의 객체 풀링 같이 이것은 마케팅을 위한 특징에 가깝습니다. 이것은 XML configuration 파일을 작게 만드는 좋은 아이디어 같지만 실제로 복잡함을 증가시킬 것입니다. 특히 많은 빈들이 정의된 대규모 프로젝트에서 더합니다. 스프링에서 autowiring과 명시적인 wiring을 섞어서 쓸 수도 있지만 이러한 일관성 없는 방식은 XML configuration을 더욱 혼란스럽게 만듭니다.

2. Use naming conventions
This is the same philosophy as for Java code. Using clear, descriptive, and consistent name conventions across the project is very helpful for developers to understand the XML configurations. For bean ID, for example, you can follow the Java class field name convention. The bean ID for an instance of OrderServiceDAO would be orderServiceDAO.For large projects, you can add the package name as the prefix of the bean ID.

이것은 java 코드에서와 같은 사상입니다. 프로젝트 전반에 거쳐 명확함, 선언적 그리고 일관된 명명규칙을 사용하면 개발자들이 XML configuration을 이해하는데 많은 도움을 줍니다. 빈 ID로 예를 들자면 Java 클래스의 필드 이름 규칙을 사용할 수 있을 것입니다. OrderServiceDAO 인스턴스의 빈 아이디는 orderServiceDAO가 될 것입니다. 대규모 프로젝트에서는 빈 ID의 접두어로 패키지 이름을 추가할 수 있을 겁니다.

3. Use shortcut forms
The shortcut form is less verbose, since it moves property values and references from child elements into attributes. For example, the following:

프로퍼티 값이나 레퍼런스를 자식 엘리먼트에서 속성으로 옮기기에 간단한 형식이 덜 장황합니다. 아래 예를 보십시오.

    <bean id="orderService"
        class="com.lizjason.spring.OrderService">
        <property name="companyName">
            <value>lizjason</value>
        </property>
        <constructor-arg>
            <ref bean="orderDAO">
        </constructor-arg>
    </bean>

can be rewritten in the shortcut form as:

이것은 다음과 같이 간단한 형식으로 다시 작성할 수 있습니다. 

    <bean id="orderService"
        class="com.lizjason.spring.OrderService">
        <property name="companyName"
            value="lizjason"/>
        <constructor-arg ref="orderDAO"/>
    </bean>

The shortcut form has been available since version 1.2. Note that there is no shortcut form for <ref local="...">.

간단한 형식은 1.2 버전부터 사용이 가능합니다. <ref local="...">을 위한 간단한 형식은 없다는 것을 염두해 두십시오.

The shortcut form not only saves you some typing, but also makes the XML configuration files less cluttered. It can noticeably improve readability when many beans are defined in a configuration file.

간단한 형식은 타이핑을 줄이는 것뿐만 아니라 XML configuration 파일을 덜 난잡하게 해 줍니다. Configuration 파일에 많은 빈들을 정의할 경우 눈에 띄게 가독성을 향상시킬겁니다.

4. Prefer type over index for constructor argument matching
Spring allows you to use a zero-based index to solve the ambiguity problem when a constructor has more than one arguments of the same type, or value tags are used. For example, instead of:

스프링은 생성자가 두 개이상의 같은 타입을 가질 때 모호한 문제를 풀기 위해 0부터 시작하는 index를 사용하는 것을 허용합니다. 예를 들면 다음과 같습니다.

    <bean id="billingService"
        class="com.lizjason.spring.BillingService">
        <constructor-arg index="0" value="lizjason"/>
        <constructor-arg index="1" value="100"/>
    </bean>

It is better to use the type attribute like this:


이것은 다음과 같이 type 속성을 사용하는게 더 낫습니다.

    <bean id="billingService"
        class="com.lizjason.spring.BillingService">
        <constructor-arg type="java.lang.String"
            value="lizjason"/>
        <constructor-arg type="int" value="100"/>
    </bean>

Using index is somewhat less verbose, but it is more error-prone and hard to read compared to using the type attribute. You should only use index when there is an ambiguity problem in the constructor arguments.

index를 사용하는 것이 어느 정도 더 간결하지만 더 에러가 발생하기 쉽고 type 속성에 비해 읽기도 어렵습니다. 생성자 아규먼트에 모호한 문제가 있을 경우에만 index를 사용하여야 합니다.

5. Reuse bean definitions, if possible
Spring offers an inheritance-like mechanism to reduce the duplication of configuration information and make the XML configuration simpler. A child bean definition can inherit configuration information from its parent bean, which essentially serves as a template for the child beans. This is a must-use feature for large projects. All you need to do is to specify abstract=true for the parent bean, and the parent reference in the child bean. For example:

Configuration 정보의 중복을 줄이고 XML configuration을 간결하게 하기 위해 스프링은 상속과 비슷한 메커니즘을 제공합니다. 자식 빈 정의는 부모 빈으로부터 configuration 정보를 상속받을 수 있습니다. 부모 빈 정의가 자식 빈을 위한 템플릿 역할을 합니다. 대규모 프로젝트에서는 반드시 사용하여할 기능입니다. 해야 할 일은 단지 부모 빈에 abstract=true로 설정하고 자식 빈에서 parent 로 참조하는 것입니다. 예를 들어보면.

    <bean id="abstractService" abstract="true"
        class="com.lizjason.spring.AbstractService">
        <property name="companyName"
            value="lizjason"/>
    </bean>     <bean id="shippingService"
        parent="abstractService"
        class="com.lizjason.spring.ShippingService">
        <property name="shippedBy" value="lizjason"/>
    </bean>

The shippingService bean inherits the value lizjason for the companyName property from the abstractService bean. Note that if you do not specify a class or factory method for a bean definition, the bean is implicitly abstract.

shippingService 빈은 abstractService 빈으로 부터 lizjason 값을 가진 companyName 속성을 상속받습니다. 만일 빈 정의에 클래스나 팩토리 메소드를 지정하지 않는다면 그 빈은 암시적으로 abstract이 된다는 것을 알아두십시오.

6. Prefer assembling bean definitions through ApplicationContext over imports
Like imports in Ant scripts, Spring import elements are useful for assembling modularized bean definitions. For example:

Ant 스크립트의 import같이 스프링의 import 엘리먼트는 빈 정의를 모듈화하여 조립하는데 유용합니다. 예를 들면:

    <beans>
        <import resource="billingServices.xml"/>
        <import resource="shippingServices.xml"/>
        <bean id="orderService"
            class="com.lizjason.spring.OrderService"/>
    <beans>

However, instead of pre-assembling them in the XML configurations using imports, it is more flexible to configure them through the ApplicationContext. Using ApplicationContext also makes the XML configurations easy to manage. You can pass an array of bean definitions to the ApplicationContext constructor as follows:

그런데, import를 이용하여 XML configuration 안에서 미리 조립하는 대신 ApplicationContext 클래스를 이용하여 구성하는 것이 보다 유연합니다. 또한 ApplicationContext를 이용하면 XML configuration을 관리하기 쉬워집니다. 다음과 같이 빈 정의의 배열을 ApplicationContext 생성자에 전달할 수 있습니다.

    String[] serviceResources =
        {"orderServices.xml",
        "billingServices.xml",
        "shippingServices.xml"};
    ApplicationContext orderServiceContext = new
        ClassPathXmlApplicationContext(serviceResources);


7. Use ids as bean identifiers
You can specify either an id or name as the bean identifier. Using ids will not increase readability, but it can leverage the XML parser to validate the bean references. If ids cannot be used due to XML IDREF constraints, you can use names as the bean identifiers. The issue with XML IDREF constraints is that the id must begin with a letter (or one of a few punctuation characters defined in the XML specification) followed by letters, digits, hyphens, underscores, colons, or full stops. In reality, it is very rare to run into the XML IDREF constraint problem.

빈 식별자로 id나 name을 지정할 수 있습니다. id를 사용하면 가독성을 향상시키지는 않지만 XML 파서가 빈 참조를 검사하는데 도움이 됩니다. XML IDREF 제약때문에 id를 사용할 수 없으면 빈 식별자로 name을 사용할 수 있습니다. XML IDREF 제약의 이슈는 id는 반드시 문자(또는 XML 스펙에 정의된 구두문자 중 하나)로 시작하여 뒤에 문자, 숫자, 하이픈, 밑줄, 콜론 또는 마침표가 옵니다. 사실, XML IDREF 제약의 문제에 빠지는 것은 매우 드문 일입니다.

8. Use dependency-check at the development phase
You can set the dependency-check attribute on a bean definition to a value other than the default none, such as simple, objects, or all, so that the container can do the dependency validation for you. It is useful when all of the properties (or certain categories of properties) of a bean must be set explicitly, or via autowiring

빈 정의에 dependency-check 속성을 기본값인 none 이나, simple, object 또는 all로 설정할 수 있습니다. 이는 dependency를 검증해 줍니다. 명시적으로든 자동(autowiring)으로 든  빈의 모든 속성(또는 속성의 어떤 카테고리들)에 반드시 값이 설정되어야 할 때 유용합니다.

    <bean id="orderService"
        class="com.lizjason.spring.OrderService"
        dependency-check="objects">
        <property name="companyName"
            value="lizjason"/>
        <constructor-arg ref="orderDAO"/>
    </bean>

In this example, the container will ensure that properties that are not primitives or collections are set for the orderService bean. It is possible to enable the default dependency check for all of the beans, but this feature is rarely used because there can be beans with properties that don't need to be set.

이 예제에서 컨테이너는 기본 타입(primitive)이나 집합 타입이 아닌 orderService 빈의 속성 값은 설정될 것을 보장합니다. 기본으로 모든 빈에 dependency 검사를 하도록 할 수도 있지만, 반드시 설정할 필요가 없는 빈의 속성도 있을 수 있기 때문에 이 기능은 거의 사용하지 않습니다.

9. Add a header comment to each configuration file
It is preferred to use descriptive ids and names instead of inline comments in the XML configuration files. In addition, it is helpful to add a configuration file header, which summarizes the beans defined in the file. Alternatively, you can add descriptions to the description element. For example:

XML configuration 파일 중간에 주석을 다는 것보다는 딱 봐도 알 수 있는(descriptive) id나 이름을 사용하는 것이 더 좋습니다. 거기에다 파일의 헤더에 빈 정의에 대한 요약을 다는 것도 많은 도움이 됩니다.
대신 다음과 같이 description 엘리먼트로 설명을 추가할 수도 있습니다.

    <beans>
        <description>
            This file defines billing service
            related beans and it depends on
            baseServices.xml,which provides
            service bean templates...
        </description>
        ...
    </beans>

One advantage of using the description element is that it is easy to for tools to pick up the description from this element.

이 description 엘리먼트를 사용하면 각종 도구에서 설명을 뽑아내기 쉬운 장점이 있습니다.

10. Communicate with team members for changes
When you are refactoring Java source code, you need to make sure to update the configuration files accordingly and notify team members. The XML configurations are still code, and they are critical parts of the application, but they are hard to read and maintain. Most of the time, you need to read both the XML configurations and Java source code to figure out what is going on.

Java 소스 코드를 리팩토링할 때 관련된 configuration 파일들을 갱신할 필요가 있으면 팀 동료에게 알려야 합니다. XML configuration 역시 코드이며 애플리케이션에서 중요한 요소 중 하나이지만 읽기도 어렵고 유지하기도 어렵습니다. 대부분의 시간동안 뭐가 어떻게 돌아가는지 파악하기 위해 XML configuration과 Java 코드 둘 다 읽어야 할 필요가 있습니다.

11. Prefer setter injection over constructor injection
Spring provides three types of dependency injection: constructor injection, setter injection, and method injection. Typically we only use the first two types.

스프링은 생성자 주입, setter 주입 그리고 메소드 주입 세 가지 의존성 주입(dependency injection) 방법을 제공합니다. 전형적으로 앞의 두 가지 방식만 사용합니다.

    <bean id="orderService"
        class="com.lizjason.spring.OrderService">
        <constructor-arg ref="orderDAO"/>
    </bean>

    <bean id="billingService"
        class="com.lizjason.spring.BillingService">
        <property name="billingDAO"
            ref="billingDAO">
    </bean>


In this example, the orderService bean uses constructor injection, while the BillingService bean uses setter injection. Constructor injection can ensure that a bean cannot be constructed in an invalid state, but setter injection is more flexible and manageable, especially when the class has multiple properties and some of them are optional.

이 예제에서 orderService 빈은 생성자 주입을 사용한 반면 billingService는 setter 주입을 사용합니다. 생성자 주입의 경우 올바르지 않은 상태로는 생성할 수 없도록 보증하지만 setter 주입이 보다 유연하고 관리하기 쉽습니다. 특히 클래스가 여러 개의 속성을 가지고 그 중 몇 개는 선택적일 경우 더욱 그렇습니다.

12. Do not abuse dependency injection
As the last point, Spring ApplicationContext can create Java objects for you, but not all Java objects should be created through dependency injection. As an example, domain objects should not be created through ApplicationContext. Spring is an excellent framework, but, as far as the readability and manageability are concerned, the XML-based configuration can become an issue when many beans are defined. Overuse of dependency injection will make the XML configuration more complicated and bloated. Remember, with powerful IDEs, such as Eclipse and IntelliJ, Java code is much easier to read, maintain, and manage than XML files!

마지막으로, 스프링 ApplicationContext 는 여러분을 위해 Java 객체를 생성해 줍니다. 그러나 모든 Java 객체가 의존성 주입을 통해 생성해야 하는 것은 아닙니다. 그 예로 도메인 객체는 ApplicationContext를 통해 생성하지 말아야 합니다. 스프링은 뛰어난 프레임워크이나 많은 빈들이 정의되면 XML 기반의 configuration이 이슈가 될 수 있으므로 어느 정도 가독성과 관리성을 고려해야 합니다. 의존성 주입을 과용하면 XML configuration은 보다 복잡해지고 비대해질 것입니다. Eclipse나 InteliJ와 같은 강력한 IDE를 사용하면 Java 코드가 XML 파일보다 훨씬 읽거나 유지하거나 관리하기가 쉽다는 것을 기억하십시오!

Conclusion
XML is the prevailing format for Spring configurations. XML-based configuration can become verbose and unwieldy when many beans are defined. Spring provides a rich set of configuration options. Appropriately using some of the options can make the XML configurations less cluttered, but other options, like autowiring, may reduce readability and maintainability. Following good practices discussed in the article may help you to create clean and readable XML configuration files!

XML은 일반적인 Spring configuration 포맷입니다. 많은 빈들을 정의할 경우 XML 기반 configuration은 장황해지고 다루기 어려워지기 쉽습니다. 스프링은 풍부한 configuration 옵션들을 지원합니다. 적절히 이 옵션들을 사용하면 XML configuration은 덜 복잡해지기도 하지만 autowiring 같은 다른 옵션들은 가독성이나 관리성을 떨어뜨립니다. 이 기사에서 논의한 좋은 실천사항들을 따른다면 깨끗하고 가독성이 좋은 XML configuration 파일들을 만드는데 도움이 될 것입니다!

Resources
The weblog post this article is based upon
The Spring framework website for further information about Spring XML configurations
The XML specification for IDREF constraints

Jason Zhicheng Li is a senior software engineer with Object Computing, Inc. in St. Louis, MO. 
반응형

'Framework > Spring' 카테고리의 다른 글

Mockito.thenThrow() 주의사항!  (0) 2021.09.25
Spring + @Lazy  (0) 2019.08.05
//