Since Spring 3, JavaConfig features are included in core Spring module, it allow developer to move bean definition and Spring configuration out of XML file into Java class.

But, you are still allow to use the classic XML way to define beans and configuration, the JavaConfig is just another alternative solution.

See the different between classic XML definition and JavaConfig to define a bean in Spring container.

Spring XML file :

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 
	<bean id="helloBean" class="com.mkyong.hello.impl.HelloWorldImpl">
 
</beans>

Equivalent configuration in JavaConfig :

package com.mkyong.config;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.mkyong.hello.HelloWorld;
import com.mkyong.hello.impl.HelloWorldImpl;
 
@Configuration
public class AppConfig {
 
    @Bean(name="helloBean")
    public HelloWorld helloWorld() {
        return new HelloWorldImpl();
    }
 
}

Spring JavaConfig Hello World

Now, see a full Spring JavaConfig example.

1. Directory Structure

See directory structure of this example.

directory structure of this example

2. Dependency Library

To use JavaConfig (@Configuration), you need to include CGLIB library. See dependencies :

	<!-- Spring 3 dependencies -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-core</artifactId>
		<version>${spring.version}</version>
	</dependency>
 
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>${spring.version}</version>
	</dependency>
 
	<!-- JavaConfig need this library -->
	<dependency>
		<groupId>cglib</groupId>
		<artifactId>cglib</artifactId>
		<version>2.2.2</version>
	</dependency>

3. Spring Bean

A simple bean.

package com.mkyong.hello;
 
public interface HelloWorld {
 
	void printHelloWorld(String msg);
 
}
package com.mkyong.hello.impl;
 
import com.mkyong.hello.HelloWorld;
 
public class HelloWorldImpl implements HelloWorld {
 
	@Override
	public void printHelloWorld(String msg) {
 
		System.out.println("Hello : " + msg);
	}
 
}

4. JavaConfig Annotation

Annotate with @Configuration to tell Spring that this is the core Spring configuration file, and define bean via @Bean.

package com.mkyong.config;
 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.mkyong.hello.HelloWorld;
import com.mkyong.hello.impl.HelloWorldImpl;
 
@Configuration
public class AppConfig {
 
    @Bean(name="helloBean")
    public HelloWorld helloWorld() {
        return new HelloWorldImpl();
    }
 
}

5. Run it

Load your JavaConfig class with AnnotationConfigApplicationContext.

package com.mkyong.core;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.mkyong.config.AppConfig;
import com.mkyong.hello.HelloWorld;
 
public class App {
	public static void main(String[] args) {
 
            ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
	    HelloWorld obj = (HelloWorld) context.getBean("helloBean");
 
	    obj.printHelloWorld("Spring3 Java Config");
 
	}
}

Output

Hello : Spring3 Java Config

Download Source Code

Download It – Spring3-JavaConfig-Example.zip (6 KB)

Reference

  1. Spring 3 JavaConfig reference



출처 - http://www.mkyong.com/spring3/spring-3-javaconfig-example/








스프링 3.0 GA 나오기 며칠 전에 쓰는 스프링 3.0 이야기.

Spring 3.0에 JavaConfig이 통합되는 과정은 그리 간단하지 않았다. M4까지 수년간 개발해왔던 JavaConfig을 완전히 코어 스프링 답게 대대적으로 변경시켜서 애노테이션 빈 설정의 자연스러운 한 가지 기능으로 통합시켰다. 기존 JavaConfig에서의 모습과는 그래서 큰 차이가 있다. 기본 아이디어만 가져왔을 뿐 완전히 새롭게 개발했다고 해도 지나친 말은 아닐 것이다.

아무튼. 자바코드를 통한 컨텍스트 설정이라는 이름으로 최종 정리된 @Configuration/@Bean 조합은 기존 @Component와 스테레오 타입 기반의 스캐너 자동인식 등록기능과 @Autowired로 대표되는 애노테이션 설정기능과 매우 긴밀하게 연결되어버렸다. 이 세가지는 거의 대부분 호환된다.

당연히 자동인식 @Component 클래스에는 @Autowired 같은 애노테이션 설정이 가능하다. 마찬가지로 @Configuration으로 만들어지는 자바코드 설정용 빈도 @Autowired를 비롯한 각종 애노테이션 설정이 먹는다. 그 덕분에 여러 개의 @Configuration 클래스 사이에 상호 DI가 가능해졌다. 또 @Configuration은 @Component를 메타 애노테이션으로 가지고 있다. 그 덕분에 자동 스캔의 대상이 된다. 굳이 XML에 빈으로 등록해줄 필요가 없다.

@Component가 붙은 클래스가 빈으로 등록되듯이 @Configuration 클래스도, 비록 설정만을 위한 것임에도 정식 빈으로 등록된다. 언제든 getBean()으로 가져와 사용할 수 있다. 이쯤 되면 @Configuration은 @Component의 일종이라는 것을 눈치챘을 것이다.

그런데 그 반대도 가능하다. @Autowired가 <bean>으로 등록되는 일반 빈이나, @Component 자동스캔 대상 빈이나, @Configuration의 설정을 위한 빈에 모두 적용되는 것처럼, 메소드 레벨에서 빈을 정의하는 @Configuration용 @Bean도 일반 빈에 그대로 적용된다.

무슨 말인가하면 @Configuration이 붙지 않은 빈, 예를 들어 @Component 자동 스캔 대상 클래스의 메소드에도 @Bean을 붙이면 그 자체로 하나의 빈 설정이 되버린다는 사실이다. 굳이 @Component 조차도 필요없다. 어떤 빈이든 @Bean만 붙이면 그 자체로 완벽한 팩토리 방식의 메소드를 이용한 빈 설정으로 인식되서 새로운 빈이 하나 추가된다.

이제는 굳이 <bean> 태그에 factory-method를 선언해줄 필요도 없게 되었다는 말이다.

 

하지만 일반 빈에서 @Bean을 사용하는 것은 사실 혼란의 가능성이 있다. 기억을 더듬어보면 3.0 개발 중에 @FactoryBean이라는 이름의 애노테이션이 존재했던 적이 있다. 그것을 더 일반화 시켜서 그냥 @Bean이라는 이름으로 통합한 것이다.

하지만 @Configuration에서 사용되는 @Bean과 @Component에서 사용되는 빈은 그 성격이 다르다.

최신 레퍼런스 매뉴얼에 보면 이런 설명이 나온다. 굵은 글씨로 표시한 부분을 잘 이해해야 한다.

The @Bean methods in a Spring component are processed differently than their counterparts inside a Spring @Configuration class. The difference is that@Componentclasses are not enhanced with CGLIB to intercept the invocation of methods and fields. CGLIB proxying is the means by which invoking methods or fields within @Configurationclasses. @Bean methods create bean metadata references to collaborating objects. Methods are not invoked with normal Java semantics. In contrast, calling a method or field within a @Component classes @Bean method has standard Java semantics.

@Configuration안의 @Bean은 메소드를 호출하는 것으로 DI가 가능하다. JavaConfig 방식이다. 이를 위해서 @Configuration빈은 CGLib을 통해서 enhanced 된다. 왜냐면 @Bean메소드로 정의된 빈이 싱글톤이라면 메소드를 여러번 호출해도 항상 동일한 오브젝트가 리턴되는 것이 보장되야 하기 때문이다. 따라서 이건 normal Java semantics가 아니다. @Configuration 클래스는 자바코드 표현을 차용한 DSL일 뿐이다. 자바코드의 semantic과 다르게 동작한다.

다음은 @Configuration 안에서 빈을 정의한 코드이다. 여기서 printer() 메소드를 호출하는 것으로 ref=”printer”와 같은 효과를 낸다. 하지만 자바의 일반 동작방식과는 달리 아무리 여러번 printer()를 호출해도 매번 동일한 오브젝트가 돌아온다.

@Bean Hello hello() {

  Hello h = new Hello();

  h.setPrinter(printer());

  h.setSubPrinter(printer());

}

@Bean Printer printer() {

  return new Printer();

}

반면에 같은 @Bean이지만 @Component나 일반 빈에서 사용되면 그 때는 standard Java semantics로 동작한다. 그 말은 enhanced되지 않는 다는 뜻이며 메소드 호출로 DI를 구성하는 것은 심각한 오류를 낳게 될 수 있다는 점이다.

이 때문에 @Component의 @Bean 안에서의 DI구현은 다른 빈을 메소드 파라미터 인젝션을 사용해서 레퍼런스를 받은 후 그것을 사용해야만 한다. 안그러면 아주 심각한, 찾기 힘든 버그가 발생할 것이다. 예를 보자. @Configuration과 비슷해보이지만 DI부분은 확연히 다르다. 여기서 publicInstance빈이 싱글톤 스코프를 보장받으려면 이를 참조하는 다른 @Bean에서는 절대 메소드를 직접 호출해서는 안된다.

이 클래스의 설정의 의미를 명확히 이해할 수 있고 @Configuration에서 쓸 때와의 차이점을 명확히 구분할 수 있으며, 이런 식으로 실전에서 자유자재로 구성할 수 있다면 스프링 3.0의 심오한 DI 세계를 마스터하는데 첫 발은 디딘 것으로 자신해도 좋을 것이다.

@Component 
public class FactoryMethodComponent {

    private static int i;

    @Bean @Qualifier("public") 
    public TestBean publicInstance() { 
        return new TestBean("publicInstance"); 
    }

    // use of a custom qualifier and autowiring of method parameters

    @Bean @BeanAge(1) 
    protected TestBean protectedInstance(@Qualifier("public") TestBean spouse, 
                                         @Value("#{privateInstance.age}") String country
) { 
        TestBean tb = new TestBean("protectedInstance", 1); 
        tb.setSpouse(tb); 
        tb.setCountry(country); 
        return tb; 
    }

    @Bean @Scope(BeanDefinition.SCOPE_SINGLETON) 
    private TestBean privateInstance() { 
        return new TestBean("privateInstance", i++); 
    }

    @Bean @Scope(value = WebApplicationContext.SCOPE_SESSION, 
                 proxyMode = ScopedProxyMode.TARGET_CLASS) 
    public TestBean requestScopedInstance() { 
        return new TestBean("requestScopedInstance", 3); 
    } 
}

한가지 아쉬운 것은 이런 혼란을 피하기 위해서 @Component에서는 @Bean 대신에 다른 이름을 사용하는 것이 좋지 않았을까 하는 점이다. 뭐.. 나름 고민 끝에 @Bean으로 통일한 것이긴 하겠지만.

 

Spring 3.0은 2.5에서 일부 시도한 DI의 변화를 거의 극한까지 밀어 붙여서 지금까지 나온 어떤 DI기술보다 가장 심오하고 이상적인 레벨의 IoC/DI 프레임워크로 변신했다. 스프링 쫌 한다는 사람도 3.0을 제대로 쓴다고 말하려면 IoC공부에 꽤 많은 시간을 다시 투자할 각오를 하는게 좋을 것이다.

나도 아직 헷갈릴 정도로.. 쉽지 않다.


출처 - http://toby.epril.com/?p=939











Posted by linuxism
,


Spring comes with a useful ‘org.springframework.mail.javamail.JavaMailSenderImpl‘ class to simplify the e-mail sending process via JavaMail API. Here’s a Maven build project to use Spring’s ‘JavaMailSenderImpl‘ to send an email via Gmail SMTP server.

1. Project dependency

Add the JavaMail and Spring’s dependency.

File : pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
  http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mkyong.common</groupId>
  <artifactId>SpringExample</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>SpringExample</name>
  <url>http://maven.apache.org</url>
 
  <repositories>
  	<repository>
  		<id>Java.Net</id>
  		<url>http://download.java.net/maven/2/</url>
  	</repository>
  </repositories>
 
  <dependencies>
 
    <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>3.8.1</version>
             <scope>test</scope>
    </dependency>
 
    <!-- Java Mail API -->
    <dependency>
	    <groupId>javax.mail</groupId>
	    <artifactId>mail</artifactId>
	    <version>1.4.3</version>
    </dependency>
 
    <!-- Spring framework -->
    <dependency>
     	    <groupId>org.springframework</groupId>
	    <artifactId>spring</artifactId>
	    <version>2.5.6</version>
    </dependency>
 
  </dependencies>
</project>

2. Spring’s Mail Sender

A Java class to send email with the Spring’s MailSender interface.

File : MailMail.java

package com.mkyong.common;
 
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
 
public class MailMail
{
	private MailSender mailSender;
 
	public void setMailSender(MailSender mailSender) {
		this.mailSender = mailSender;
	}
 
	public void sendMail(String from, String to, String subject, String msg) {
 
		SimpleMailMessage message = new SimpleMailMessage();
 
		message.setFrom(from);
		message.setTo(to);
		message.setSubject(subject);
		message.setText(msg);
		mailSender.send(message);	
	}
}

3. Bean configuration file

Configure the mailSender bean and specify the email details for the Gmail SMTP server.

File : Spring-Mail.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
	<property name="host" value="smtp.gmail.com" />
	<property name="port" value="587" />
	<property name="username" value="username" />
	<property name="password" value="password" />
 
	<property name="javaMailProperties">
	   <props>
       	      <prop key="mail.smtp.auth">true</prop>
       	      <prop key="mail.smtp.starttls.enable">true</prop>
       	   </props>
	</property>
</bean>
 
<bean id="mailMail" class="com.mkyong.common.MailMail">
	<property name="mailSender" ref="mailSender" />
</bean>
 
</beans>

4. Run it

package com.mkyong.common;
 
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class App 
{
    public static void main( String[] args )
    {
    	ApplicationContext context = 
             new ClassPathXmlApplicationContext("Spring-Mail.xml");
 
    	MailMail mm = (MailMail) context.getBean("mailMail");
        mm.sendMail("from@no-spam.com",
    		   "to@no-spam.com",
    		   "Testing123", 
    		   "Testing only \n\n Hello Spring Email Sender");
 
    }
}



출처 - http://www.mkyong.com/spring/spring-sending-e-mail-via-gmail-smtp-server-with-mailsender/



Posted by linuxism
,

xml - XSLT

Development/XML 2013. 8. 10. 18:06


XSLT.svg
확장자.xsl .xslt
MIME 종류application/xslt+xml[1]
개발W3C
파일 포맷 종류스타일시트 언어


XSLT(Extensible Stylesheet Language Transformations)는 XML 문서를 다른 XML 문서로 변환하는데 사용하는 XML 기반 언어이다. W3C에서 제정한 표준으로 XML 변환 언어를 사용하여 XML 문서로 바꿔주며, 탐색하기 위해 XPath를 사용한다.

원본 문서는 변경되지 않으며, 원본 문서를 기반으로 새로운 문서가 생성된다.[2] 새 문서는 표준 XML 문법 또는 HTML, 일반 텍스트 형식으로 출력된다.[3] XSLT는 XML 데이터를 웹 페이지로 표시하기 위해 HTML 또는 XHTML 문서로 변환할 때 자주 사용된다. 변환은 클라이언트나 서버에서 동적으로 수행되거나, 퍼블리싱 단계에서 수행되기도 한다. XML을 PDFPostScriptAWTPNG와 같은 다양한 형태로 바꿀 수 있는 XML-FO로 변환할 때도 사용한다. XSLT는 일반적으로 서로 다른 XML 스키마를 사용하는 XML 메시지를 변환하거나, 하나의 스키마 안에서 문서를 변경하기 위해 사용한다(예: 메시지에서 불필요한 부분 삭제).

개요[편집]

XSLT 처리의 구성 요소는 다음과 같다.

  • 하나 이상의 XML 원본 문서
  • 하나 이상의 XSLT 스타일시트 모듈
  • XSLT 템플릿 처리 엔진(프로세서)
  • 하나 이상의 결과 문서

XSLT는 일반적으로 XML 원본 문서와 XSLT 스타일시트를 입력으로 받아 문서를 출력한다. XSLT 스타일시트는 템플릿 룰:명령어(template rules: instructions와 프로세서가 출력 문서를 제작하는 데 필요한 지침을 담고 있다.

템플릿 룰 처리[편집]

XSLT은 선언적인 언어이다. 템플릿 룰은 조건에 따라 어떤 동작을 수행하는지 나열하는 대신, 지정한 XPath 형태의 패턴과 일치하는 노드를 어떻게 처리할지를 정의한다. 템플릿은 프로세서가 패턴을 결과 트리 형태로 나타낼 수 있는 표현식을 담고 있다.

프로세서는 고정된 알고리즘을 따른다. 스타일시트는 이미 읽어와서 준비되어 있고, 프로세서는 입력 XML 문서에서 원본 트리를 만든다. 원본 트리의 루트 노드부터 스타일시트에서 가장 잘 맞는 템플릿을 찾아 변환한다. 각 템플릿의 명령어는 결과 트리의 노드를 생성하거나, 원본 트리의 다음 노드를 처리하도록 지시한다.

프로세서 구현[편집]

XSLT 프로세서 구현은 크게 서버 측과 클라이언트 측으로 나뉜다. 클라이언트 XSLT 프로세싱은 Microsoft Internet Explorer에서 1999년부터 가능하지만, XSLT를 지원하지 않는 이전 브라우저와 다른 브라우저가 널리 퍼져 있어 도입 속도가 느리다. 비슷한 이유로 XSLT 2.0의 도입도 제한되어 있다.

XSLT 프로세서는 단일 제품으로 제작되거나, 웹 브라우저, 애플리케이션 서버, Java나 .NET 등 프레임워크 또는 운영체제의 컴포넌트로 제작된다.

XSLT와 XPath[편집]

XSLT는 원본 문서 트리의 부분을 식별하고 연산을 수행하기 위해 XPath 언어를 사용한다. XSLT 1.0은 XPath 1.0을 사용하며, XSLT 2.0은 XPath 2.0을 사용한다. 두 가지 스펙은 모두 같은 날 출판되었다.

XSLT와 XQuery 비교[편집]

XSLT의 기능은 다량의 XML 문서의 쿼리 언어로 사용되는 XQuery와 겹친다.

XSLT 2.0과 XQuery 1.0 표준은 W3C의 별도 작업 그룹이 개발하였으며, 접근 방식을 통일하기 위해 협업하였다. 데이터 모델과, 타입 시스템, 함수 라이브러리를 공유하며, 둘 다 XPath 2.0을 보조 언어로 사용한다.

두 언어는 서로 다른 환경의 요구를 반영한다. XSLT의 주요 목적은 XML을 처리하여 사람이 화면, 웹, 인쇄물로 읽을 수 있게 하는 것이다. XQuery의 주로 전통적인 SQL로 데이터베이스의 쿼리 언어로 여긴다.

XSLT 예제[편집]

다음은 입력 XML 문서의 예시이다.

<?xml version="1.0" ?>
<persons>
  <person username="JS1">
    <name>John</name>
    <family-name>Smith</family-name>
  </person>
  <person username="MI1">
    <name>Morka</name>
    <family-name>Ismincius</family-name>
  </person>
</persons>

다음은 XSLT 스타일시트의 예시이다.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/> 
 
  <xsl:template match="/persons">
    <root>
      <xsl:apply-templates select="person"/> 
    </root>
  </xsl:template>
 
  <xsl:template match="person">
    <name username="{@username}">
      <xsl:value-of select="name" />
    </name>
  </xsl:template>
 
</xsl:stylesheet>

다음은 결과 XML 문서의 예시이다.

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <name username="JS1">John</name>
  <name username="MI1">Morka</name>
</root>

주석[편집]

  1.  XSL Transformations (XSLT) Version 2.0
  2.  XSL Transformations (XSLT)
  3.  See e. g., http://www.w3.org/TR/xslt#output, specifying alternate output methods.

바깥 고리[편집]



출처 - http://ko.wikipedia.org/wiki/XSLT



'Development > XML' 카테고리의 다른 글

jaxen - XPath and Default Namespace handling  (0) 2013.02.20
XQuery  (0) 2013.02.20
XSL(Extensible Stylesheet Language)  (0) 2013.02.19
XPath  (0) 2013.02.19
XML - XML 스키마(XSD) 및 xsi 접두어 의미  (0) 2012.10.02
Posted by linuxism
,