Spring SpEL을 이용하여 Value세팅하기

스프링에서 단순한 값의 주입은 <value> 태그나 @Value를 이용하여 넘겨줄 값을 하드코딩 하여주면 된다. 간단하게 이전까지 정리했던 Value주입을 요약정리 부터 남긴다.

[xml이용시]

setter값 주입

 

1
2
3
4
5
<bean id="..." class="..."/>
    <property name="strName">    
        <value>이지수</value>
    </property>
</bean>
cs 

 

constructor값 주입

1
2
3
4
5
<bean id="..." class="..."/>
    <constructor-arg type="String">    
        <value>이지수</value>
    </constructor-arg>
</bean>




[Annotation이용시]

setter값 주입 방법1

1
2
3
4
5
6
7
8
9
10
@Service("beanId")
public Class A {
 
    private String name;
    
    @Autowired    
    public void setName(@Value("이지수")String name) {
        this.name = name;
    }
}
cs


setter값 주입 방법2

1
2
3
4
5
6
7
@Service("beanId")
public Class A {
    
    @Value("이지수")
    private String name;
    
}
cs


* 방법1, 2 둘 중에 아무거나 쓰면 된다. 방법2가 굳이 별도의 setter를 정의하지 않아도 되어 편리하다. 
* 방법1은 컴포넌트 스캔을 통해서 @Value("") 에 해당하는 String객체를 만들고 Autowired를 통해서 주입시켜주기 때문에 Autowired 필요


constructor값 주입

1
2
3
4
5
6
7
8
9
10
11
@Service("beanId")
public Class A {
    
    private String name;
 
    @Autowired
    public A(@Value("이지수")String name){
        this.name = name;
    }
    
}
cs

 


* 생성자 주입에서 @#Autowired는 여러생성자가 있는 경우 오직 하나의 생성자에만 지정할 수 있다.

* app-context~.xml 파일에 String으로 bean을 미리 생성해 놓았다면 @Value태그 없이 Autowired 태그만으로 주입이 가능하다.

SpEL을 이용하여 Value세팅하기

스프링 3.0 버젼부터 SpEL(Spring Expression Language)를 지원한다. 여타의 다른 EL과 유사한 개념으로 표현식을 스프링 xml파일이나 Annotation에 적용 방법을 조금더 간단하고 효율적으로 적용할 수 있는 방법이다. 런타임시에 표현식 내에서 연산이 가능하며, 다른 bean이 갖는 property, 별도소스코딩 없이 properties 파일에 접근 하는 것이 가능하다. 


xml에서 SpEL


[ConfigValue.class]

- 설정과 관련된 정보를 담고 있는 Class 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.ljs.message.config;
 
public class ConfigValue {
 
    private String     strVal   = "스트링";
    private int        intVal   = 10000;
    private float    floatVal = 10.32f;
    private boolean    boolVal  = true;
    private Long    longVal  = 10000000000l;
    
    public String getStrVal() {
        return strVal;
    }
    public void setStrVal(String strVal) {
        this.strVal = strVal;
    }
    public int getIntVal() {
        return intVal;
    }
    public void setIntVal(int intVal) {
        this.intVal = intVal;
    }
    public float getFloatVal() {
        return floatVal;
    }
    public void setFloatVal(float floatVal) {
        this.floatVal = floatVal;
    }
    public boolean isBoolVal() {
        return boolVal;
    }
    public void setBoolVal(boolean boolVal) {
        this.boolVal = boolVal;
    }
    public Long getLongVal() {
        return longVal;
    }
    public void setLongVal(Long longVal) {
        this.longVal = longVal;
    }
}
cs


[ValueProvider Class]

- main메소드에서 ValueProvider Class Bean를 사용할 것이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.ljs.message.provider;
 
 
public class ValueProvider  {
    
    /*
     * Class Members
     */
    private String     strVal;
    private int        intVal;
    private float    floatVal;
    private boolean    boolVal;
    private Long    longVal;
 
    /*
     * Getters and Setters 
     */
    public String getStrVal() {
        return strVal;
    }
 
    public void setStrVal(String strVal) {
        this.strVal = strVal;
    }
 
    public int getIntVal() {
        return intVal;
    }
 
    public void setIntVal(int intVal) {
        this.intVal = intVal;
    }
 
    public float getFloatVal() {
        return floatVal;
    }
 
    public void setFloatVal(float floatVal) {
        this.floatVal = floatVal;
    }
 
    public boolean isBoolVal() {
        return boolVal;
    }
 
    public void setBoolVal(boolean boolVal) {
        this.boolVal = boolVal;
    }
 
    public Long getLongVal() {
        return longVal;
    }
 
    public void setLongVal(Long longVal) {
        this.longVal = longVal;
    }
    
    /*
     * Ovverride toString method
     */
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("STRING : "     + strVal + "\n" );
        sb.append("INT : "         + intVal + "\n" );
        sb.append("FLOAT : "     + floatVal + "\n" );
        sb.append("BOOLEAN : "    + boolVal + "\n" );
        sb.append("LONG : "     + longVal + "\n" );
        return sb.toString();
    }
}
cs

 


[main Class]

- ValueProvider Bean을 획득하여 toString호출

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.ljs.message;
 
import org.springframework.context.support.GenericXmlApplicationContext;
 
import com.ljs.message.provider.ValueProvider;
 
public class ApplicationMain {
 
    public static void main(String[] args) {
        // ApplicationContext 부트스트랩
        GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
        ctx.load("classpath:META-INF/spring/app-context-xml.xml");
        ctx.refresh();
 
        // bean use
        ValueProvider provider = (ValueProvider) ctx.getBean("valueProvider");
        System.out.println(provider.toString());
 
        ctx.close();
    }
}
cs


[app-context-xml.xml]

- Spring 설정에 관련된 xml

- valueProvider bean생성시 configValueBean빈에 값에 SpEL을 통해서 접근

- SpEL은 #{SpEL}의 형식을 따른다.

- 아래 intVal+1처럼 연산자 지원가능

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
        
    <bean id="configValueBean" class = "com.ljs.message.config.ConfigValue"/>
    
    <bean id="valueProvider" class="com.ljs.message.provider.ValueProvider">
        <property name="strVal"><value>#{configValueBean.strVal}</value></property>
        <property name="intVal"><value>#{configValueBean.intVal + 1}</value></property>
        <property name="floatVal"><value>#{configValueBean.floatVal}</value></property>
        <property name="boolVal"><value>#{configValueBean.boolVal}</value></property>
        <property name="longVal"><value>#{configValueBean.longVal}</value></property>
    </bean>    
</beans>
cs

 


Annotation에서 SpEL

어노테이션 방식에서도 xml방식과 별다른 바 없다. 주목할 점은 여태까지 @Service를 이용하여 bean을 등록하였는데, 이번에는 @Component를 사용했다는 점이다. 이 둘은 바꾸어 써도 효과는 동일하다. @Service는 @Component를 특화해 만든 것으로 대상 Class가 비지니스 서비스를 다른 레이어에 제공해준다는 사실을 표시해주는 어노테이션일 뿐이다.  (컴포넌트를 의미적으로 구분하기 위해서 세분화 해놓은 것에 불과하다.) 


[ConfigValue.class]

- @Service를 사용하지 않고, @Component를 사용하여 DI대상 Bean을 정의

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.ljs.message.config;
 
import org.springframework.stereotype.Component;
 
@Component("configValueBean")
public class ConfigValue {
 
    private String     strVal   = "스트링";
    private int        intVal   = 10000;
    private float    floatVal = 10.32f;
    private boolean    boolVal  = true;
    private Long    longVal  = 10000000000l;
    
    public String getStrVal() {
        return strVal;
    }
    public void setStrVal(String strVal) {
        this.strVal = strVal;
    }
    public int getIntVal() {
        return intVal;
    }
    public void setIntVal(int intVal) {
        this.intVal = intVal;
    }
    public float getFloatVal() {
        return floatVal;
    }
    public void setFloatVal(float floatVal) {
        this.floatVal = floatVal;
    }
    public boolean isBoolVal() {
        return boolVal;
    }
    public void setBoolVal(boolean boolVal) {
        this.boolVal = boolVal;
    }
    public Long getLongVal() {
        return longVal;
    }
    public void setLongVal(Long longVal) {
        this.longVal = longVal;
    }
}
cs

 


[ValueProvider Class]

- 등록된 bean에 대하여 아래와 같이 SpEL방식으로 접근이 가능

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package com.ljs.message.provider;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
 
@Service("valueProvider")
public class ValueProvider  {
    
    /*
     * Class Members
     */
    @Value("#{configValueBean.strVal}")
    private String     strVal;
    @Value("#{configValueBean.intVal+1}")
    private int        intVal;
    @Value("#{configValueBean.floatVal}")
    private float    floatVal;
    @Value("#{configValueBean.boolVal}")
    private boolean    boolVal;
    @Value("#{configValueBean.longVal}")
    private Long    longVal;
 
    /*
     * Getters and Setters 
     */
    public String getStrVal() {
        return strVal;
    }
 
    public void setStrVal(String strVal) {
        this.strVal = strVal;
    }
 
    public int getIntVal() {
        return intVal;
    }
 
    public void setIntVal(int intVal) {
        this.intVal = intVal;
    }
 
    public float getFloatVal() {
        return floatVal;
    }
 
    public void setFloatVal(float floatVal) {
        this.floatVal = floatVal;
    }
 
    public boolean isBoolVal() {
        return boolVal;
    }
 
    public void setBoolVal(boolean boolVal) {
        this.boolVal = boolVal;
    }
 
    public Long getLongVal() {
        return longVal;
    }
 
    public void setLongVal(Long longVal) {
        this.longVal = longVal;
    }
    
    /*
     * Ovverride toString method
     */
    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("STRING : "     + strVal + "\n" );
        sb.append("INT : "         + intVal + "\n" );
        sb.append("FLOAT : "     + floatVal + "\n" );
        sb.append("BOOLEAN : "    + boolVal + "\n" );
        sb.append("LONG : "     + longVal + "\n" );
        return sb.toString();
    }
}
cs


[Main Class]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.ljs.message;
 
import org.springframework.context.support.GenericXmlApplicationContext;
 
import com.ljs.message.provider.ValueProvider;
 
public class ApplicationMain {
 
    public static void main(String[] args) {
        // ApplicationContext 부트스트랩
        GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
        ctx.load("classpath:META-INF/spring/app-context-annotation.xml");
        ctx.refresh();
 
        // bean use
        ValueProvider provider = (ValueProvider) ctx.getBean("valueProvider");
        System.out.println(provider.toString());
        
        ctx.close();
    }
}
cs


[app-context-annotation.xml]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
    
    
    
    <!--스프링이 코드기반에서 의존성 요구조건을 스캔하게끔 세팅-->    
    <context:annotation-config/>
    
    <!--스프링이 코드에서 지정된 패키지(및 하위)아래에 있는 주입 가능한 빈을 모두 스캔하도록 세팅-->
    <context:component-scan base-package="com.ljs.message"/>
        
</beans>
cs




여기까지 SpEL방식으로 bean에 값을 주입하는 방법이였다. 그런데 이렇게 직접 bean property에 접근하는 방법보다는 properties와 같은 외부파일에서 값을 읽어오는 방식이 훨씬 좋을 것으로 보인다. db접속정보라던지, 외부서버 정보 같은 부분... 


다운로드


이 글을 공유하기

댓글

Email by JB FACTORY