- Today
- Total
- java
- μλ£κ΅¬μ‘°
- Algorithm
- CS
- Graph
- array
- leetcode
- OOP
- ꡬν
- MST
- spring
- 그리λ
- μμμ λ ¬
- pytorch
- database
- λ°±μλ
- BFS
- νλ‘κ·Έλλ¨Έμ€
- μ‘Έμ μν
- λ°μ΄ν°λ² μ΄μ€
- λ¬Έλ²
- μΈν΄
- tree
- dp
- PS
- λ°±μ€
- μλ°
- μλ°μμ μ
- λ€μ΅μ€νΈλΌ
- 벨λ§ν¬λ
Partially Committed
[Spring] λΉ μλͺ μ£ΌκΈ° μ½λ°±, λΉ μ€μ½ν λ³Έλ¬Έ
λΉ μλͺ μ£ΌκΈ° μ½λ°±
μ ν리μΌμ΄μ μ μ€ν μ΄μ μ λ°μ΄ν°λ² μ΄μ€ 컀λ₯μ νμ΄λ λ€νΈμν¬ μμΌκ³Ό κ°μ΄ μμ μ§μ μ νμν μ°κ²°μ 미리 ν΄λκ³ μ ν리μΌμ΄μ μ’ λ£ μμ μ μμ νκ² μ’ λ£νκΈ° μν΄μλ κ°μ²΄μ μ΄κΈ°ν λ° μ’ λ£ μμ μ΄ νμνλ€. μ΄λ Spring μμ μ΄λ»κ² ꡬνν μ μμκΉ?
μ€νλ§ λΉμ κ°μ²΄λ₯Ό μμ±νκ³ μμ‘΄κ΄κ³λ₯Ό λͺ¨λ λ€ μ£Όμ ν λ€μμμμΌ λ°μ΄ν°λ₯Ό μ¬μ©ν μ μλ€. κ·Έλμ μ΄κΈ°ν μμ μ μμ‘΄κ΄κ³ μ£Όμ μ΄ λͺ¨λ λλ λ€μμ νΈμΆν΄μΌ ν ν λ°, μ΄ μμ μ μ΄λ»κ² νλ©΄ μ ννκ² μ μ μμκΉ? μ΄λ₯Ό μν΄ μ€νλ§μ μμ‘΄κ΄κ³ μ£Όμ μ΄ μλ£λλ©΄ μ€νλ§ λΉμκ² μ½λ°± λ©μλλ₯Ό ν΅ν΄ μ΄κΈ°ν μμ μ μλ €μ£Όλ κΈ°λ₯μ μ 곡νλ€. κ·Έλ¦¬κ³ μ€νλ§ μ»¨ν μ΄λκ° μ’ λ£λκΈ° μ§μ μ μλ©Έ μ½λ°±μ μ£ΌκΈ° λλ¬Έμ μ΄λ₯Ό μ΄μ©νμ¬ μμ νκ² μ’ λ£ μμ μ μ§νν μ μλ€.
[ μ€νλ§ λΉμ μ΄λ²€νΈ λΌμ΄ν μ¬μ΄ν΄ ]
μ€νλ§ μ»¨ν μ΄λ μμ± βΆ μ€νλ§ λΉ μμ± βΆ μμ‘΄κ΄κ³ μ£Όμ βΆμ΄κΈ°ν μ½λ°± βΆ μ¬μ© βΆ μλ©Έμ μ½λ°± βΆ μ€νλ§ μ’ λ£
* μ΄κΈ°ν μ½λ°± : λΉμ΄ μμ±λκ³ λΉμ μμ‘΄κ΄κ³ μ£Όμ μ΄ μλ£λ νμ νΈμΆ
* μλ©Έμ μ½λ°± : λΉμ΄ μλ©ΈλκΈ° μ§μ μ νΈμΆ
[μ€νλ§μ μλͺ μ£ΌκΈ° μ½λ°±]
1. μΈν°νμ΄μ€ (InitializingBean, DisposableBean)
2. μ€μ μ 보μ μ΄κΈ°ν λ©μλ, μ’ λ£ λ©μλ μ§μ
3. @PostConstruct, @PreDestroy μ λ Έν μ΄μ μ§μ
(μ°Έκ³ )
κ°μ²΄μ μμ±κ³Ό μ΄κΈ°νλ λΆλ¦¬νλ κ²μ΄ μΌλ°μ μΌλ‘ μ’λ€. μμ±μλ νλΌλ―Έν°λ₯Ό λ°κ³ λ©λͺ¨λ¦¬λ₯Ό ν λΉν΄μ κ°μ²΄λ₯Ό μμ±νλ μ± μμ κ°μ§κ³ , μ΄κΈ°νλ μμ±λ κ°μ νμ©νμ¬ μΈλΆ 컀λ₯μ μ μ°κ²°νλ λ±μ λ¬΄κ±°μ΄ λμμ μννλ€. κ·Έλ¬λ―λ‘ μ΄λ¬ν μν μ λΆλΌνλ κ²μ΄ μ μ§λ³΄μ κ΄μ μμ μΌλ°μ μΌλ‘ μ’λ€.
μ±κΈν€ λΉμ μ€νλ§ μ»¨ν μ΄λκ° μ’ λ£λ λ κ°μ΄ μ’ λ£λκΈ° λλ¬Έμ μ€νλ§ μ»¨ν μ΄λκ° μ’ λ£λκΈ° μ§μ μ μλ©Έ μ μ½λ°±μ΄ μΌμ΄λλ€. μ±κΈν€κ³Ό κ°μ΄ 컨ν μ΄λμ μμκ³Ό μ’ λ£κΉμ§ μμ‘΄νλ λΉλ μμ§λ§ λΌμ΄ν μ¬μ΄ν΄μ΄ 짧μ λΉλ μλ€. μ΄λ¬ν λΉλ€μ 컨ν μ΄λμ 무κ΄νκ² μλ©Έμ μ½λ°±μ΄ λ°μνλ€.
# μΈν°νμ΄μ€ (InitializingBean, DisposableBean)
μλ μ½λμ κ°μ΄ InitializingBean, DisposableBean μΈν°νμ΄μ€λ₯Ό ꡬνν¨μ λ°λΌμ λΉ μλͺ μ£ΌκΈ° μ½λ°±μ λ°μ μ μλ€.
package hello.core.lifercycle;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class NetworkClient implements InitializingBean, DisposableBean {
private String url; // μ μν΄μΌν μλ² URL
public NetworkClient() {
System.out.println("μμ±μ νΈμΆ, url = " + url);
}
public void setUrl(String url) {
this.url = url;
}
// μλΉμ€λ₯Ό μμν λ νΈμΆνλ λ©μλ
public void connect() {
System.out.println("connect: " + url);
}
public void call(String message) {
System.out.println("call: " + url + " message = " + message);
}
//μλΉμ€ μ’
λ£ μ νΈμΆ
public void disconnect() {
System.out.println("close " + url);
}
@Override
public void afterPropertiesSet() throws Exception {
// μμ‘΄κ΄κ³ μ£Όμ
μ΄ λλλ©΄ νΈμΆνλ€.
System.out.println("NetworkClient.afterPropertiesSet");
connect();
call("μ΄κΈ°ν μ°κ²° λ©μΈμ§");
}
@Override
public void destroy() throws Exception {
// μ€νλ§ μ»¨ν
μ΄λκ° μ’
λ£λκΈ° μ§μ μ νΈμΆνλ€.
System.out.println("NetworkClient.destroy");
disconnect();
}
}
π’ μ΄κΈ°ν, μλ©Έ μΈν°νμ΄μ€μ λ¨μ
- InitializingBean, DisposableBean μΈν°νμ΄μ€λ μ€νλ§ μ μ© μΈν°νμ΄μ€μ΄λ€. μ΄λ₯Ό μ¬μ©νλ©΄ μ€νλ§ μ μ© μΈν°νμ΄μ€μ μ½λκ° μμ‘΄νκ² λλ€.
- μ΄κΈ°ν, μλ©Έ λ©μλμ μ΄λ¦μ λ³κ²½ν μ μλ€.
- μ½λλ₯Ό κ³ μΉ μ μλ μΈλΆ λΌμ΄λΈλ¬λ¦¬μ μ μ©ν μ μλ€.
βΆ ν΄λΉ λ°©λ²μ μ€νλ§ μ΄μ°½κΈ°μ μ£Όλ‘ μ¬μ©νλ λ°©λ²μ΄κ³ , νμ¬λ λ€λ₯Έ λ°©λ²μ΄ ν¨μ¬ μ’λ€.
# λΉ λ±λ‘ μ΄κΈ°ν, μλ©Έ λ©μλ μ§μ
μ€μ μ 보μ @Bean(initMethod="init", destroyMethod="close") μ κ°μ΄ μ΄κΈ°ν, μλ©Έ λ©μλλ₯Ό μ§μ ν μ μλ€.
@Configuration
static class LifeCycleConfig {
@Bean(initMethod = "init", destroyMethod = "close")
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dev");
return networkClient;
}
}
μμ κ°μ΄ ν¨μ λ°λΌ λ©μλ μ΄λ¦μ μμ λ‘κ² μ€μ ν μ μμΌλ―λ‘ μ€νλ§ λΉμ΄ μ€νλ§ μ½λμ μμ‘΄νμ§ μκ² λλ€. λν μ½λκ° μλ μ€μ μ 보λ₯Ό μ¬μ©νλ―λ‘ μ½λλ₯Ό κ³ μΉ μ μλ μΈλΆ λΌμ΄λΈλ¬λ¦¬μλ μ΄κΈ°ν, μ’ λ£ λ©μλλ₯Ό μ μ©ν μ μλ€.
@Bean μ destroyMethod μ default λ (inferred) μ΄λ€. λλΆλΆμ λΌμ΄λΈλ¬λ¦¬μμ μ’ λ£ λ©μλλ close, shutdown μ΄λΌλ μ’ λ£ λ©μλλ₯Ό μ¬μ©νλλ° destroyMethod κ° (infferred) μ΄λΌλ©΄ close, shutdown λΌλ μ΄λ¦μ κ°μ§ λ©μλλ₯Ό μλμΌλ‘ νΈμΆν΄μ€λ€. destroyMethod="" λΌκ³ ν΄μ£Όλ©΄ μΆλ‘ νμ§ μλλ€.
# μ λ Έν μ΄μ @PostConstruct, @PreDestroy
@PostConstruct
public void init() throws Exception {
// μμ‘΄κ΄κ³ μ£Όμ
μ΄ λλλ©΄ νΈμΆνλ€.
System.out.println("NetworkClient.init");
connect();
call("μ΄κΈ°ν μ°κ²° λ©μΈμ§");
}
@PreDestroy
public void close() throws Exception {
// μ€νλ§ μ»¨ν
μ΄λκ° μ’
λ£λκΈ° μ§μ μ νΈμΆνλ€.
System.out.println("NetworkClient.close");
disconnect();
}
- μμ κ°μ΄ μ€νλ§μμλ @PostConstruct, @PreDestroy μ λ Έν μ΄μ μ μ¬μ©νλ λ°©λ²μ κΆμ₯νλ€.
- μ€νλ§μ μ’ μμ μΈ κΈ°μ μ΄ μλλΌ JSR-250 μ΄λΌλ μλ° νμ€μΌλ‘ μ€νλ§μ΄ μλ λ€λ₯Έ 컨ν μ΄λμμλ λμνλ€.(javax)
- νμ§λ§ μΈλΆ λΌμ΄λΈλ¬λ¦¬μλ μ μ©ν μ μλ€. μΈλΆ λΌμ΄λΈλ¬λ¦¬λ₯Ό μ΄κΈ°ν, μ’ λ£ν΄μΌ νλ κ²½μ° @Bean(initMethod="init", destroyMethod="close") μ νμ©νμ.
# λΉ μ€μ½ν
κΈ°λ³Έμ μΌλ‘ μ€νλ§ λΉμ μ±κΈν€ μ€μ½νλ‘ μμ±λκΈ° λλ¬Έμ μ€νλ§ μ»¨ν μ΄λμ΄ μμλλ©΄μ μμ±λκ³ , μ€νλ§ μ»¨ν μ΄λκ° μ’ λ£λ λκΉμ§ μ μ§λλ€. μ€νλ§μμλ λ€μν λΉ μ€μ½νλ₯Ό μ§μνλ©° μλμ κ°λ€.
1. μ±κΈν€ : κΈ°λ³Έ μ€μ½νλ‘, μ€νλ§μ 컨ν μ΄λμ μμ~μ’ λ£κΉμ§ μ μ§λλ κ°μ₯ λμ λ²μμ μ€μ½ν
2. νλ‘ν νμ : νλ‘ν νμ λΉμ μμ±κ³Ό μμ‘΄κ΄κ³ μ£Όμ κΉμ§λ§ κ΄μ¬νκ³ λλ κ΄λ¦¬νμ§ μλ λ§€μ° μ§§μ λ²μμ μ€μ½ν
3. μΉ κ΄λ ¨ μ€μ½ν
- request: μΉ μμ²μ΄ λ€μ΄μ€κ³ λκ°λ κΉμ§ μ μ§λ¨.
- session: μΉ μΈμ μ΄ μμ±λκ³ μ’ λ£λ λ κΉμ§ μ μ§λ¨.
- application: μΉμ μλΈλ¦Ώ 컨ν μ€νΈμ κ°μ λ²μλ‘ μ μ§λ¨.
# νλ‘ν νμ μ€μ½ν
μ±κΈν€ μ€μ½νμ λΉκ΅ν΄λ³΄μ. μ±κΈν€ μ€μ½νλ λΉμ μ‘°νν μμ μ€νλ§ μ»¨ν μ΄λκ° νμ κ°μ μΈμ€ν΄μ€μ μ€νλ§ λΉμ λ°ννλ€. νμ§λ§ νλ‘ν νμ μ€μ½νλ₯Ό μ€νλ§ μ»¨ν μ΄λμ μ‘°ννλ©΄, νμ μλ‘μ΄ μΈμ€ν΄μ€λ₯Ό μμ±ν΄μ λ³ννλ€. μ€νλ§ μ»¨ν μ΄λκ° νλ‘ν νμ λΉμ μμ±ν λ, νμν μμ‘΄κ΄κ³ λν μ£Όμ ν΄μ£Όμ΄μ ν΄λΌμ΄μΈνΈμκ² λ°ννλ€. μ€νλ§ μ»¨ν μ΄λλ νλ‘ν νμ λΉμ μμ±νκ³ , μμ‘΄κ΄κ³λ₯Ό μ£Όμ νκ³ μ΄κΈ°ννλ κ² κΉμ§λ§ μ²λ¦¬νλ©° μ΄ν κ΄λ¦¬λν΄λΌμ΄μΈνΈκ° μ§μ ν΄μ£Όμ΄μΌ νλ€. κ·Έλμ νλ‘ν νμ μ€μ½ν νμ @PreDestroy μ κ°μ μ’ λ£ λ©μλκ° νΈμΆλμ§ μλλ€.
νλ‘ν νμ λΉμ νΉμ§μ μ 리νλ©΄ μλμ κ°λ€.
- μ€νλ§ μ»¨ν μ΄λμ μμ²ν λ λ§λ€ μλ‘ μμ±λλ€.
- μ€νλ§ μ»¨ν μ΄λλ νλ‘ν νμ λΉ μμ±κ³Ό μμ‘΄κ΄κ³ μ£Όμ , μ΄κΈ°νκΉμ§λ§ κ΄μ¬νλ€.
- μ’ λ£ λ©μλκ° νΈμΆλμ§ μλλ€.
- κ·Έλ κΈ° λλ¬Έμ νλ‘ν νμ λΉμ νλ‘ν νμ λΉμ μ‘°νν ν΄λΌμ΄μΈνΈκ° μ§μ κ΄λ¦¬ν΄μΌ νλ€. μ’ λ£ λ©μλμ λν νΈμΆλ νμνλ€λ©΄ ν΄λΌμ΄μΈνΈκ° μ§μ ν΄μ€μΌ νλ€λ κ²μ΄λ€.
# νλ‘ν νμ μ€μ½νμ μ±κΈν€ λΉμ ν¨κ» μ¬μ©ν μ λ°μνλ λ¬Έμ μ
- μ€νλ§ μ»¨ν μ΄λμ νλ‘ν νμ μ€μ½ν λΉμ μμ²νλ©΄ μμ² μ λ§λ€ μλ‘μ΄ κ°μ²΄ μΈμ€ν΄μ€λ₯Ό μμ±ν΄μ λ°ννλ€. λ€λ§ μ±κΈν€ λΉκ³Ό νλ‘ν νμ λΉμ κ°μ΄ μ¬μ©ν κ²½μ° μλν λλ‘ λμνμ§ μμ μ μμΌλ―λ‘ μ£Όμν΄μΌνλ€.
- μ€νλ§μ μΌλ°μ μΌλ‘ μ±κΈν€ λΉμ μ¬μ©νλ€. κ·Έλμ μ±κΈν€ λΉμ΄ νλ‘ν νμ λΉμ μ¬μ©νλλ°, μ±κΈν€ λΉμ μμ± μμ μλ§ μμ‘΄κ΄κ³λ₯Ό μ£Όμ λ°κΈ° λλ¬Έμ νλ‘ν νμ λΉμ΄ μλ‘ μμ±λλ©΄ μ±κΈν€ λΉκ³Ό ν¨κ» μ μ§λλ κ²μ΄ λ¬Έμ λ₯Ό μ λ°νλ€. νλ‘ν νμ λΉμ μ¬μ©νλ λͺ©μ μ μ¬μ©ν λ λ§λ€ μλ‘ μμ±λμ΄μ μ¬μ©νλ κ²μΌ ν λ°, μ΄λ κ² νλ©΄ μ£Όμ μμ μλ§ μλ‘ μμ±νκ² λλλ° μ΄λ μλμ λ°νλ€.
- μ΄μ κ°μ΄ μ±κΈν€ λΉκ³Ό νλ‘ν νμ λΉμ ν¨κ» μ¬μ© μ, μ±κΈν€ λΉμ΄ νλ‘ν νμ μ μ¬μ©ν λλ§λ€ μ€νλ§ μ»¨ν μ΄λμ μλ‘ μμ²νλ κ²μ΄ κ°μ₯ κ°λ¨νλ€. μ΄μ κ°μ΄ νμν μμ‘΄κ΄κ³λ₯Ό μ§μ μ°Ύλ κ²μ Dependency Lookup(DL) μ΄λΌκ³ νλ€. μ΄ λ°©λ²μΌλ‘ ν΄κ²°νλ κ²½μ°, μ€νλ§ μ»¨ν μ΄λμ μ’ μμ μΈ μ½λκ° λ§λ€μ΄μ§ μ λ°μ μκ³ λ¨μ ν μ€νΈκ° μ΄λ ΅λ€. λ± DL κΈ°λ₯λ§ μμΌλ©΄ μ’κ² λλ°...?
- κ·Έκ² λ°λ‘ ObjectProvider μ΄λ€. (κ³Όκ±°μλ ObjectFactory μλλ°, μ¬κΈ°μ μ¬λ¬ κΈ°λ₯λ€μ΄ μΆκ°λμ΄ ObjectProvider κ° λ§λ€μ΄μ‘λ€.)
@Scope("singleton")
static class ClientBean {
@Autowired
private ObjectProvider<PrototypeBean> prototypeBeanProvider;
public int logic() {
PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
}
- prototypeBeanProvider.getObject() μ ν΅ν΄μ νμ μλ‘μ΄ νλ‘ν νμ λΉμ΄ μμ±λλ€.
- ObjectProvider μ getObject() μ νΈμΆνλ©΄ λ΄λΆμμ μ€νλ§ μ»¨ν μ΄λλ₯Ό ν΅ν΄ λΉμ μ°Ύμμ λ°ννλ€.(DL)
- ObjectFactory : κΈ°λ₯μ΄ λ¨μ, λ³λ λΌμ΄λΈλ¬λ¦¬ νμ μκ³ μ€νλ§μ μμ‘΄
- ObjectProvider : ObjectFactory μμ, μ΅μ , μ€νΈλ¦Ό μ²λ¦¬μ κ°μ μ¬λ¬ κΈ°λ₯μ΄ μκ³ λ³λμ λΌμ΄λΈλ¬λ¦¬κ° νμμμΌλ©° μμ μ€νλ§μ μμ‘΄.
JSR-330 Provider
- javax.inject.Provider μ΄λΌλ μλ° νμ€μ μ¬μ©νλ λ°©λ²μ΄ μλ€. (spring 3.0 μ jakarta.inject.Provider)
- μ΄λ₯Ό μ¬μ©νλ €λ©΄ javax.inject:javax.inject:1 λΌμ΄λΈλ¬λ¦¬λ₯Ό gradle μ μΆκ°ν΄μΌ ν¨!
@Scope("singleton")
static class ClientBean {
@Autowired
private Provider<PrototypeBean> prototypeBeanProvider;
public int logic() {
PrototypeBean prototypeBean = prototypeBeanProvider.get();
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
}
- μ΄λ μλ° νμ€μ΄κ³ κΈ°λ₯μ΄ λ¨μνλ―λ‘ λ¨μ ν μ€νΈλ₯Ό λ§λκ±°λ mock μ½λλ₯Ό λ§λ€κΈ° μμνλ€.
- μλ° νμ€μ΄κΈ° λλ¬Έμ μ€νλ§μ΄ μλ λ€λ₯Έ 컨ν μ΄λμμλ μ¬μ©μ΄ κ°λ₯νλ€λ κ²μ΄ νΉμ§!
[μ 리]
1. νλ‘ν νμ λΉμ μ¬μ©ν λλ§λ€ μμ‘΄κ΄κ³ μ£Όμ μ΄ μλ£λ μλ‘μ΄ κ°μ²΄κ° νμν κ²½μ°μ μ¬μ©νλ€. μ€λ¬΄μμλ μ±κΈν€ λΉμΌλ‘ λλΆλΆμ λ¬Έμ λ₯Ό ν΄κ²°ν μ μκΈ° λλ¬Έμ νλ‘ν νμ λΉμ μ§μ μ μΌλ‘ μ¬μ©νλ μΌμ λλ¬Όλ€κ³ νλ€.
2. ObjectProvider, JSR330 Provider λ±μ νλ‘ν νμ λΏλ§μ΄ μλλΌ DL μ΄ νμν κ²½μ°μ μ΄λ₯Ό μ΄μ©νμ¬ ν΄κ²°ν μ μμΌλ κΈ°μ΅ν΄λμ.
3. μ½λλ₯Ό μ€νλ§μ΄ μλ λ€λ₯Έ 컨ν μ΄λμμλ μ¬μ©ν κ°λ₯μ±μ΄ μλ€λ©΄ JSR-330 Provider μ μ¬μ©ν΄μΌλ§ νλ€. κ·Έλ° κ²½μ°κ° μμ κ² κ°λ€λ©΄ μ€νλ§μ΄ μ 곡ν΄μ£Όλ ObjectProvider μ μ¬μ©νλ κ²μ΄ νΈνλ€.
# μΉ μ€μ½ν
- μΉ νκ²½μμλ§ λμν¨.
- νλ‘ν νμ κ³Όλ λ¬λ¦¬ μ€μ½νμ μ’ λ£μμ κΉμ§ κ΄λ¦¬ν¨.(μ’ λ£ λ©μλκ° νΈμΆλ¨)
request : HTTP μμ²μ΄ λ€μ΄μ€κ³ λκ° λ κΉμ§ μ μ§λλ μ€μ½νλ‘, κ°κ°μ http μμ²λ§λ€ λ³λμ λΉ μΈμ€ν΄μ€κ° μμ±λκ³ κ΄λ¦¬λ¨.
session : HTTP Session κ³Ό λμΌν μλͺ μ£ΌκΈ°λ₯Ό κ°μ§
application : μλΈλ¦Ώ 컨ν μ€νΈ(ServletContext) μ λμΌν μλͺ μ£ΌκΈ°λ₯Ό κ°μ§
websocket : μΉ μμΌκ³Ό λμΌν μλͺ μ£ΌκΈ°λ₯Ό κ°μ§
Reference
'π» Study ! > Spring' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
μΈν 리μ μ΄μμ κ°μκΈ° μ€νλ§ νλ‘μ νΈμ λΉ¨κ°μ€μ΄ λ무νλ€λ©΄?! (0) | 2023.08.05 |
---|---|
JSP MVC ν¨ν΄ (0) | 2023.05.14 |
[Spring] μμ‘΄κ΄κ³ μλ μ£Όμ (0) | 2023.01.16 |
[Spring] μ±κΈν€ 컨ν μ΄λ (0) | 2023.01.12 |
[Spring] Spring κ³Ό OOP (0) | 2023.01.04 |