1220 - 1226
# 1220 - 1226
# 1221 - ์ ๋ตํจํด๊ณผ ์ปค๋งจ๋ํจํด
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ฌ ์ฌ์ฉํ๋ ๋ ๊ฐ์ง ํจํด์ธ ์ ๋ต ํจํด๊ณผ ์ปค๋งจ๋ ํจํด์ ์ฐจ์ด
# ์ ๋ตํจํด
์ ๋ต ํจํด์ ํ๋ก๊ทธ๋จ์ด ์งํ๋๋ฉด์ ์บก์ํ๋ ๋ก์ง์ ์ ํํ ์ ์๊ฒ ํ๋ ๋์์ธ ํจํด์ด๋ค. ๋ก์ง ์คํ์ ์ธํฐํ์ด์ค์ ์์กด์ ์ํค๊ณ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๋ก์ง๋ค์ ์ ๋ฌํด์ค์ผ๋ก์จ ๋ถ๊ธฐ์ฒ๋ฆฌ ์์ด ์ ์ฐ์์ ๊ฐ์ถ ์๊ฐ ์๋ค.
- ์์ ์ฝ๋
public class PeopleWithMovement {
private Transportation transportation;
public PeopleWithMovement(Transportation transportation) {
this.transportation = transportation;
}
public void move(String start, String end) {
transportation.move(start, end);
}
public void changeTransporation(Transportation transportation) {
this.transportation = transportation;
}
}
์ ๋ต์ ํํญ ์ฃผ์ฒด์ธ Transporation์ ์ธํฐํ์ด์ค๋ก ๋ถ๋ฆฌ๋์ด ์บก์ํ ๋์ด ์๋ค.
public interface Transportation {
void move(String start, String end);
}
//
public class Bicycle implements Transportation {
@Override
public void move(String start, String end){
System.out.println("์ถ๋ฐ์ : " + start + "์์ ๋ชฉ์ ์ง : " + end + "๊น์ง `์์ ๊ฑฐ`๋ก ์ด๋ํฉ๋๋ค.");
}
}
//
public class Bus implements Transportation {
@Override
public void move(String start, String end){
System.out.println("์ถ๋ฐ์ : " + start + "์์ ๋ชฉ์ ์ง : " + end + "๊น์ง `๋ฒ์ค`๋ก ์ด๋ํฉ๋๋ค.");
}
}
Transporation์ ๊ตฌํํ์ฌ Bus์ Bicycle ์ฝ๋ ์์ฑ
public class Main {
public static void main(String[] args) {
Bicycle bicycle = new Bicycle();
Bus bus = new Bus();
PeopleWithMovement whybeFirst = new PeopleWithMovement(bicycle);
whybeFirst.move("์์์ ", "๋์ ");
PeopleWithMovement whybeSecond = new PeopleWithMovement(bus);
whybeSecond.move("์์์ ", "๋์ ");
PeopleWithMovement whybeChangeMovement = new PeopleWithMovement(bicycle);
whybeChangeMovement.move("์์์ ", "์ค๊ฐ์ง์ ");
whybeChangeMovement.changeTransporation(bus);
whybeChangeMovement.move("์ค๊ฐ์ง์ ", "๋์ ");
}
}
์คํ ๊ฒฐ๊ณผ
์ถ๋ฐ์ : ์์์ ์์ ๋ชฉ์ ์ง : ๋์ ๊น์ง `์์ ๊ฑฐ`๋ก ์ด๋ํฉ๋๋ค.
์ถ๋ฐ์ : ์์์ ์์ ๋ชฉ์ ์ง : ๋์ ๊น์ง `๋ฒ์ค`๋ก ์ด๋ํฉ๋๋ค.
์ถ๋ฐ์ : ์์์ ์์ ๋ชฉ์ ์ง : ์ค๊ฐ์ง์ ๊น์ง `์์ ๊ฑฐ`๋ก ์ด๋ํฉ๋๋ค.
์ถ๋ฐ์ : ์ค๊ฐ์ง์ ์์ ๋ชฉ์ ์ง : ๋์ ๊น์ง `๋ฒ์ค`๋ก ์ด๋ํฉ๋๋ค.
# ์ปค๋งจ๋ ํจํด
์ปค๋งจ๋ ํจํด์ ์์ฒญ์ ํ๋ก ์ฒ๋ฆฌํ ์ ์๋๋ก ์์ฒญ์ ์ํํ๋ ์ฌ๋ฌ ์ธ์๋ฅผ ํจ๊ป ํจํค์งํ์ฌ ๋์ค์ ์ฒ๋ฆฌํ ์ ์๋๋ก ๋ง๋ค์ด์ฃผ๋ ํ๋ ์ค์ฌ ๋์์ธ ํจํด์ด๋ค. ์ปค๋งจ๋๋ฅผ ์คํ์ํค๋ ๊ฐ์ฒด๋ ์ปค๋งจ๋ ๋ด๋ถ์ ์์์ ๋ํด์ ์จ๊น์ผ๋ก์จ ์ฝ๋์ ์ ์ฐ์ฑ์ ๊ฐ์ง ์ ์๋ค.
- ์์ ์ฝ๋
public class PeopleWithLottery {
private List<LotteryCommand> lotteryCommands;
public PeopleWithLottery(List<LotteryCommand> lotteryCommands) {
this.lotteryCommands = lotteryCommands;
}
public void addLotteryCommand(LotteryCommand lotteryCommand) {
lotteryCommands.add(lotteryCommand);
}
public void scratchAllLottery() {
for (int i = 0; i < lotteryCommands.size(); i++) {
LotteryCommand lotteryCommand = lotteryCommands.get(i);
lotteryCommand.scratch();
}
//์ด๊ธฐํ
lotteryCommands = new LinkedList<>();
}
}
public interface LotteryCommand {
void scratch();
}
public class InstantScratch implements LotteryCommand {
private InstantLottery instantLottery;
private Account account;
public InstantScratch(InstantLottery instantLottery, Account account) {
this.instantLottery = instantLottery;
this.account = Account;
}
@Override
public void scratch() {
//instantLottery์ ๋น์ฒจ์ ํ์ธํ๊ณ account์ ๋์ ์ง์ด ๋ฃ๋ ๋ก์ง
}
}
public class InstantLottery {
private boolean win;
public InstantLottery(boolean win) {
this.win = win;
}
public boolean isWin() {
return win;
}
}
public class Account {
private int balance;
public void putMoney(int money) {
balance += money;
}
}
public class Main {
public static void main(String[] args) {
PeopleWithLottery whybe = new PeopleWithLottery(new LinkedList<>());
Account ์์ด๋นํต์ฅ = new Account();
//์ฆ์๋ณต๊ถ ๊ตฌ์
for (int i = 0; i < 10; i++) {
//์ฆ์๋ณต๊ถ ์์ฑ ๋ก์ง
InstantLottery instantLottery = new InstantLottery(๋น์ฒจ์ฌ๋ถ);
//์ฆ์๋ณต๊ถ๊ธ๊ธฐํ์ ๊ฐ์ฒด ์์ฑ ๋ฐ ์ปค๋งจ๋ ๋ชฉ๋ก์ ์ถ๊ฐ
InstantScratch ์ฆ์๋ณต๊ถ๊ธ๊ธฐ์ปค๋งจ๋ = new InstantScratch(์ฆ์๋ณต๊ถ, ์์ด๋นํต์ฅ);
whybe.addLotteryCommand(์ฆ์๋ณต๊ถ๊ธ๊ธฐ์ปค๋งจ๋);
}
whybe.scratchAllLotery();
}
}
๋น์ฒจ์ ํ์ธํ๊ณ ํต์ฅ์ ๋์ ์ถ๊ฐํ๋ ๊ฒ์ ์บก์ํํ๊ณ , ๊ธ๋ ํ์๋ฅผ ํธ์ถํ๋ ๊ฐ์ฒด(People), ๋ช ๋ น์ ๋ด์ฅํ๋ ๊ฐ์ฒด(LotteryCommand) ๊ทธ๋ฆฌ๊ณ ๋ช ๋ น ์ํ์ผ๋ก ์ธํ์ฌ ์ํฅ์ ๋ฐ๋ ๊ฐ์ฒด(MyAccount)๊ฐ ๋ชจ๋ ๋ค๋ฅด๊ฒ ๊ตฌ์ฑ.
public class NumberScratch implements LotteryCommand {
private Set<Integer> winners;
private NumberLottery numberLottery;
private Account account;
public NumberScratch(Set<Integer> winners, NumberLottery numberLottery, Account account) {
this.winners = winners;
this.numberLottery = numberLottery;
this.account = account;
}
@Override
public void scratch() {
// winners์ numberLottery๋ฅผ ๋น๊ตํ์ฌ ๋น์ฒจ๊ธ์ ๊ณ์ฐํ๊ณ
// account์ ํด๋น ๊ธ์ก์ ์
๊ธํ๋ ๋ก์ง
}
}
public class NumberLottery {
private Set<Integer> numbers;
public NumberLottery(Set<Integer> numbers) {
this.numbers = numbers;
}
public int rank(Set<Integer> winners) {
// ๋น์ฒจ ๋ฒํธ์ ๋น๊ตํ์ฌ ์์ ์ ๋ฑ์๋ฅผ ๊ณ์ฐํ๋ ๋ก์ง
}
}
public class Main {
public static void main(String[] args) {
PeopleWithLottery whybe = new PeopleWithLottery(new LinkedList<>());
Account ์์ดํต์ฅ = new Account();
//์ฆ์๋ณต๊ถ ๊ตฌ์
for (int i = 0; i < 10; i++) {
//๋ฒํธ์ ๋ณต๊ถ ์์ฑ ๋ก์ง
NumberLottery ๋ฒํธ์๋ณต๊ถ = new NumberLottery(์ ํํ ๋ฒํธ);
//๋ฒํธ์๋ณต๊ถ๊ธ๊ธฐํ์ ๊ฐ์ฒด ์์ฑ ๋ฐ ์ปค๋งจ๋ ๋ชฉ๋ก์ ์ถ๊ฐ
NumberScratch ๋ฒํธ์๋ณต๊ถ๊ธ๊ธฐ์ปค๋งจ๋ = new NumberScratch(์ด๋ฒ์ฃผ ๋น์ฒจ๋ฒํธ, ๋ฒํธ์๋ณต๊ถ, ์์ดํต์ฅ);
whybe.addLotteryCommand(๋ฒํธ์๋ณต๊ถ๊ธ๊ธฐ์ปค๋งจ๋);
}
whybe.scratchAllLottery();
}
}
ํ์๋ฅผ ์บก์ํํ์ฌ ๋ณต๊ถ์ ๊ธ๋ ํ์๋ฅผ ํธ์ถํ๋ ๊ฐ์ฒด์ธ PeopleWithLottery์ ๋ช ๋ น ์ํ์ผ๋ก ์ธํ์ฌ ์ํฅ์ ๋ฐ๋ ๊ฐ์ฒด์ ํฐ ๋ณํ๋ฅผ ๊ฑฐ์น์ง ์๋๋ก ๋ง๋ฌ
# ์ ๋ตํจํด๊ณผ ์ปค๋งจ๋ํจํด์ ์ฐจ์ด
์ ๋ต ํจํด์ ์ด๋ป๊ฒ
๋ผ๋ ์ธก๋ฉด์ ์ง์ค. ์ปค๋งจ๋ ํจํด์ ๋ฌด์
์ ์ด์
# 1224 - Multipart
# Multipart๋?
- ์น ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญ์ ๋ณด๋ผ ๋, http ํ๋กํ ์ฝ์ ๋ฐ๋ ๋ถ๋ถ์ ๋ฐ์ดํฐ๋ฅผ ์ฌ๋ฌ ๋ถ๋ถ์ผ๋ก ๋๋ ์ ๋ณด๋ด๋ ๊ฒ. ์น ํด๋ผ์ด์ธํธ๊ฐ ์๋ฒ์๊ฒ ํ์ด์ ์ ๋ก๋ ํ ๋, http ํ๋กํ ์ฝ์ ๋ฐ๋ ๋ถ๋ถ์ ํ์ผ์ ๋ณด๋ฅผ ๋ด์์ ์ ์ก์ ํ๋๋ฐ, ํ์ผ์ ํ๋ฒ์ ์ฌ๋ฌ๊ฐ ์ ์ก์ ํ๋ฉด body ๋ถ๋ถ์ ํ์ผ์ด ์ฌ๋ฌ๊ฐ์ ๋ถ๋ถ์ผ๋กค ์ฐ๊ฒฐ๋์ด ์ ์ก๋๋ค. ์ด๋ ๊ฒ ์ฌ๋ฌ ๋ถ๋ถ์ผ๋ก ๋๋์ด์ ์ ์ก๋๋ ๊ฒ์ Multipart data๋ผ๊ณ ํ๋ค.
- ๋ณดํต ํ์ผ์ ์ ์กํ ๋ ์ฌ์ฉํ๋ค.
# HttpServletRequest๋ ํ์ผ ์ ๋ก๋๋ฅผ ์ง์ํ์ง ์๋๋ค.
- HttpServletRequest๋ ์น ํด๋ผ์ด์ธํธ๊ฐ ์ ๋ฌํ๋ Multipart ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ฒ ์ฒ๋ฆฌํ๋ ๋ฉ์๋๋ฅผ ์ ๊ณตํ์ง ์๋๋ค. (HttpServletRequest๋ http ํ๋กํ ์ฝ์ body ๋ถ๋ถ์ ์ฝ์ด๋ค์ด๋ input ์คํธ๋ฆผ์์ ์ง์, ์ฌ์ฉ์๋ ์ด๋ฐ input ์คํธ๋ฆผ์ ์ด์ฉํด์ Multipart๋ถ๋ถ์ ์ ๋๋์ด์ ์ฌ์ฉํด์ผํ๋ค. ๋ณดํต์ ์ง์ ๊ตฌํํ์ง ์๊ณ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉ)
- ์๋ธ๋ฆฟ์์ ํ์ผ ์ ๋ก๋๋ฅผ ์ฒ๋ฆฌํ๋ ค๋ฉด ๋ณ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค. ๋ํ์ ์ธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ํ์น ์ฌ๋จ์ commons-filedupload์ด๋ค.
# Spring MVC์์์ ํ์ผ ์ ๋ก๋
Spring MVC์์ ํ์ผ ์ ๋ก๋ ํ๋ ค๋ฉด ๋ช๊ฐ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ค์ ์ ์ถ๊ฐ
- commons-fileupload, commons-io ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ถ๊ฐ
- MultipartResolver Bean ์ถ๊ฐ
- DispatcherServlet์ ์ค๋น๊ณผ์ ์์ "multipart/form-data"๊ฐ ์์ฒญ์ผ๋ก ์ฌ ๊ฒฝ์ฐ MultipartResolver๋ฅผ ์ฌ์ฉํ๋ค. (MultipartFile ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ MultipartResolver Bean์ด ๋ฑ๋ก๋์ด์์ด์ผ ํ๋ค.)
@Bean
public MultipartResolver multipartResolver(){
org.springframework.web.multipart.commons.CommonsMultipartResolver multipartResolver = new
org.springframework.web.multipart.commons.CommonsMultipartResolver();
multipartResolver.setMaxUplaodSize(10485760); //1024 * 1024 * 10 (์ต๋ 10MB)
return multipartResolver;
}
package org.springframework.boot.autoconfigure.web.servlet;
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class })
@ConditionalOnProperty(prefix = "spring.servlet.multipart", name = "enabled", matchIfMissing = true)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(MultipartProperties.class)
public class MultipartAutoConfiguration {
private final MultipartProperties multipartProperties;
public MultipartAutoConfiguration(MultipartProperties multipartProperties) {
this.multipartProperties = multipartProperties;
}
@Bean
@ConditionalOnMissingBean({ MultipartConfigElement.class, CommonsMultipartResolver.class })
public MultipartConfigElement multipartConfigElement() {
return this.multipartProperties.createMultipartConfig();
}
@Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
@ConditionalOnMissingBean(MultipartResolver.class)
public StandardServletMultipartResolver multipartResolver() {
StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
return multipartResolver;
}
}
MultipartResolver๋ SpringMVC์์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ฑ๋กํด์ฃผ์ง ์์ง๋ง, SpringBoot์์๋ ์์ ๊ฐ์ด MultipartAutoConfigurationํด๋์ค์์ MultipartResolver Bean์ด ๋ฑ๋ก๋์ด์์ง ์๋ ๊ฒฝ์ฐ ์๋์ผ๋ก Bean์ ๋ฑ๋กํด์ค๋ค. ๋ฐ๋ผ์ SpringBoot์์๋ ๋ณ๋์ ์ค์ ์์ด MultipartFile ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
# 1225 - @AuthenticationPrincipal
์คํ๋ง ์ํ๋ฆฌํฐ๋ SecurityContext์ ์ธ์ฆ๋ Authentication ๊ฐ์ฒด๋ฅผ ๋ฃ์ด๋๊ณ ํ์ฌ ์ค๋ ๋ ๋ด์์ ๊ณต์ ๋๋๋ก ๊ด๋ฆฌํ๊ณ ์๋ค. ๋ณดํต์ ์ธ์ฆ ์ดํ @AuthenticationPrincipal ์ด๋ ธํ ์ด์ ์ ํตํด UserDetails ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ์ ์ ๊ฐ์ฒด๋ฅผ ์ฃผ์ ํ ๋ ์ฌ์ฉํ๋ ํธ์ด๋ค.
๊ด๋ จ ํด๋์ค์ ์ธํฐํ์ด์ค
- SecurityContext : ์ธํฐํ์ด์ค. Security Context ์ธํฐํ์ด์ค. Authentication์ ๋ํ ์ ๊ทผ getter๋ฅผ ์ ์ํด ๋์๋ค.
- SecurityContextImpl : ํด๋์ค. SecurityContext ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๊ฐ์ฒด Authentication ๊ฐ์ฒด์ ๋ํ getter/setter๋ฅผ ์ ์ํด ๋์ ๊ฐ์ฒด. ํด๋น ๊ตฌํ์ฒด๋ฅผ ํตํด ๋ด๋ถ์ ์ผ๋ก ํ์ฌ ์ค๋ ๋์ Security Context๋ฅผ ์์ฑํ์ฌ ์ธ์ฆ ํ Authentication ๊ฐ์ฒด๋ฅผ ๋ฃ์ด๋๋ ์ญํ ์ ํ๋ค.
- Authentication : ์ธ์ฆ ์ ๋ณด์ ๋ํ ๋ถ๋ถ์ ์ ์ํด๋์ ์ธํฐํ์ด์ค. Principal๊ณผ ๊ฐ์ Credentials, Authorities ์ ๋ํ ์ ์๊ฐ ๋์ด์๋ค. ์ฌ๋ฌ ๊ตฌํ์ฒด๊ฐ ์๋ค. (ex. UsernamePasswordAuthenticationToken)
- Principal์ ์๋ฏธ๋ "์ธ์ฆ๋๋ ์ฃผ์ฒด์ ID"
- Credentials์ "์ฃผ์ฒด๊ฐ ์ ํํ์ง ์ฆ๋ช ํ๋ ๊ฒ"
- Authorities๋ "๊ถํ"
- UserDetails : ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๊ฐ์ง๋ ์ธํฐํ์ด์ค. ์ด๋ฅผ ๊ตฌํํ์ฌ ์ค์ ๋ก๊ทธ์ธ์ ์ฌ์ฉํ ํด๋์ค๋ฅผ ๋ง๋ค๋ฉด ๋๊ณ , ์คํ๋ง ์ํ๋ฆฌํฐ ๋ด๋ถ์ ์ผ๋ก ์ง์ ์ฌ์ฉํ์ง๋ ์๊ณ Authentication์ผ๋ก ์บก์ํํ์ฌ ์ ์ฅ๋๋ค. ๋ฐ๋ผ์ UserDetails๊ตฌํ์ฒด์ ์ ๋ณด๋ Spring Security Context์ ์ ์ฅ๋ Authentication ๊ฐ์ฒด๊ฐ ๊ฐ์ ธ๊ฐ๋ค.
- HandlerMethodArgumentResolver : ์ธํฐํ์ด์ค. ํน์ ์ ๋ต์ ๋ฐ๋ผ ํ request์์ ๋์ด์จ ์ธ์๋ค์ ๋ฉ์๋ ํ๋ผ๋ฏธํฐ๋ก ํด์ํ ์ ์๋๋ก ๋์์ค
- AuthenticationPrincipalArgumentResolver : ์คํ๋ง ์ํ๋ฆฌํฐ์์ HandlerMethodArgumentResolver๋ฅผ ๊ตฌํํ ๊ตฌํ์ฒด๋ก @AuthenticationPrincipal ์ด๋ ธํ ์ด์ ์ด ์ค์ ๋ก ์ฌ์ฉ๋๋ ๋ถ๋ถ.
# ๋์ ์๋ฆฌ
ํ์ฌ ์ค๋ ๋๊ฐ ์ธ์ ์ ๋ฌผ๊ณ ์๋ค๋ฉด ์ด๋ฏธ SecurityContextHolder์ getContext() ๋ฉ์๋๋ฅผ ํตํด SecurityContext ๊ฐ์ฒด๋ฅผ ์ป๊ณ ๊ทธ ์์ getAuthentication() ๋ฉ์๋๋ฅผ ํตํด Authentication (์ธ์ฆ๊ฐ์ฒด)๋ฅผ ์ป์ ์ ์๋ค.
@PostMapping(value = "/logout",
consumes = MediaTypes.HAL_JSON_VALUE,
produces = MediaTypes.HAL_JSON_VALUE)
public Object logout(@AuthenticationPrincipal SecurityUser securityUser,
@RequestHeader("Authorization") String authorization) throws Exception {
// ์ปจํธ๋กค๋ฌ ๋ก์ง
}
Spring Security๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, AuthenticationPrincipalArgumentResolver ํด๋์ค๋ฅผ ํ์ฉํ์ฌ resolveArgument ๋ฉ์๋๋ฅผ ๊ตฌํํ๊ณ SecurityContext์ ์ ์ฅ๋ ์ธ์ฆ๊ฐ์ฒด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก Authentication ๊ฐ์ฒด๋ฅผ ๊บผ๋ด์ค๊ฒ ๋๋ค.
public final class AuthenticationPrincipalArgumentResolver implements HandlerMethodArgumentResolver {
private ExpressionParser parser = new SpelExpressionParser();
private BeanResolver beanResolver;
@Override
public boolean supportsParameter(MethodParameter parameter) {
return findMethodAnnotation(AuthenticationPrincipal.class, parameter) != null;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) {
// Security Context์์ ๊บผ๋ด์ ๊ฐ์ฒด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ค.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication == null) {
return null;
}
// ์ธ์ฆ๊ฐ์ฒด์์ Principal์ ๊บผ๋ธ๋ค.
Object principal = authentication.getPrincipal();
// ํด๋น ์ด๋
ธํ
์ด์
์ด ๋ถ์ ํ๋ผ๋ฏธํฐ๊ฐ ์กด์ฌํ๋์ง ์ฐพ๋๋ค.
AuthenticationPrincipal annotation = findMethodAnnotation(AuthenticationPrincipal.class, parameter);
String expressionToParse = annotation.expression();
if (StringUtils.hasLength(expressionToParse)) {
StandardEvaluationContext context = new StandardEvaluationContext();
context.setRootObject(principal);
context.setVariable("this", principal);
context.setBeanResolver(this.beanResolver);
Expression expression = this.parser.parseExpression(expressionToParse);
principal = expression.getValue(context);
}
if (principal != null && !parameter.getParameterType().isAssignableFrom(principal.getClass())) {
if (annotation.errorOnInvalidType()) {
throw new ClassCastException(principal + " is not assignable to " + parameter.getParameterType());
}
return null;
}
// principal ๋ฆฌํด
return principal;
}
public void setBeanResolver(BeanResolver beanResolver) {
this.beanResolver = beanResolver;
}
private <T extends Annotation> T findMethodAnnotation(Class<T> annotationClass, MethodParameter parameter) {
T annotation = parameter.getParameterAnnotation(annotationClass);
if (annotation != null) {
return annotation;
}
Annotation[] annotationsToSearch = parameter.getParameterAnnotations();
for (Annotation toSearch : annotationsToSearch) {
annotation = AnnotationUtils.findAnnotation(toSearch.annotationType(), annotationClass);
if (annotation != null) {
return annotation;
}
}
return null;
}
}
์ปจํธ๋กค๋ฌ์ ํ๋ผ๋ฏธํฐ๋ง๋ค ํด๋น resolveArgument ๋ฉ์๋๊ฐ ์คํ๋๋ค.