@Autowired
란, 스프링 DI(Dependency Injection)에서 사용되는 어노테이션입니다. @Autowired
를 설정한 메서드가 자동으로 호출되고, 인스턴스가 자동으로 주입됩니다. 객체간의 의존성이 존재할 경우 개발자가 직접 객체를 생성하거나 제어하는 것이 아니라,
제어반전에 의하여 특정 객체에 필요한 다른 객체를 프레임워크가 자동으로 연결시켜주는
것을 말한다.
개발자는 자신에게 필요한 객체를 직접 할당하지 않고, 인터페이스를 통해 선언한
객체에 스프링 프레임워크에 의해 주입받아 사용할 수 있기 때문에 비지니스 로직에만
집중할 수 있다.
개발자는 객체를 선언만 할 뿐, 할당은 프레임워크에서 자동으로 이루어진다.
Component스캔을 통해 스프링의 관리대상이됨
public class Member {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public interface MemberRepository {
// 회원 저장
Member save(Member member);
// 전체 찾기
List<Member> findAll();
}
DB가 아닌 메모리에 저장
@Repository
public class JdbcMemberRepository implements MemberRepository {
//주입
private final DataSource dataSource;
// 생성자가 하나일땐 생략 가능
// @Autowired
public JdbcMemberRepository(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public Member save(Member member) {
String sql = "INSERT INTO MEMBER VALUES (member_seq.nextval, ?)";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();
String generatedColums[] = { "ID" };
pstmt = conn.prepareStatement(sql, generatedColums);
pstmt.setString(1, member.getName());
pstmt.executeUpdate();
rs = pstmt.getGeneratedKeys();
if (rs.next()) {
member.setId(rs.getInt(1));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return member;
}
@Override
public List<Member> findAll() {
String sql = "select * from member";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
List<Member> members = null;
try {
conn = dataSource.getConnection();
pstmt = conn.prepareStatement(sql);
rs = pstmt.executeQuery();
members = new ArrayList<Member>();
while (rs.next()) {
Member member = new Member();
member.setId(rs.getInt("id"));
member.setName(rs.getString("name"));
members.add(member);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return members;
}
}
@Service
public class MemberService {
// Service에서 join메서드와 findMembers를 호출해서 회원가입과 전체회원조회
// MemberRepository memberRepository = new MemoryMemberRepository();
private final MemberRepository memberRepository;
@Autowired
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
// 회원가입
// 파라미터로 member받아옴
public int join(Member member) {
//save메서드 호출 member를 넘겨준다
memberRepository.save(member);
//member의 Id만 넘겨준다
return member.getId();
}
// 전체회원 조회
public List<Member> findMembers(){
// memberRepository에 findAll메서드로 받은 것을 전체리턴
return memberRepository.findAll();
}
}
@Controller
public class MemberController {
//스프링스럽게 사용하는것 X
//MemberService mService = new MemberService();
// 스프링스럽게 작업하기
// 중간에 memberservice가 다른영역으로 교체될 일이 없기 때문에 private final로 잠군다
// service는 Spring Container에 하나만 생성 및 등록해서 같이 공유해서 쓸 수 있다.
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
/* 1.
* 필드 주입(Field Injection)
* - final 키워드를 사용할 수 없어, 순환 참조가 발생할 수 있다. 권장X
*/
//@Autowired private final MemberService memberService;
/* 2.
* Setter Injection(수정자 주입)
* - public으로 노출이 되기 때문에 다른곳에서 주입 가능하다.
*/
// private MemberService memberService;
// @Autowired
// public void setMember(MemberService memberService) {
// this.memberService = memberService;
// }
// 회원가입 폼태그
@GetMapping(value = "/members/new")
public String createForm() {
// createMemberForm.html 생성
return "members/createMemberForm";
}
// createMemberForm에서 post방식으로 전달함
@PostMapping(value = "/members/new")
public String create(MemberFormDTO form){
Member member = new Member();
// 폼데이터로 받아온 setName세팅
// id값은 seq로 repository에 자동증가 세팅해놨음
member.setName(form.getName());
// 의존성주입으로 만든 memberService에서 join에서 member넘겨준다
memberService.join(member);
// 홈 화면으로 돌린다.
// 회원가입 완료후 입력했던 데이터는 지워야함 redirect
return "redirect:/";
//return "forward:/";
}
// 회원목록 확인
@GetMapping("/members")
public String list(Model model) {
List<Member> members = memberService.findMembers();
model.addAttribute("members",members);
//memberList.html 생성
return "members/memberList";
}
}
@Controller
public class HomeController {
// 기본 localhost:9090으로 들어오면 여기를 호출
@GetMapping("/")
public String home() {
return "home";
}
}
<html xmlns:th="http://www.thymeleaf.org"><head>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div>
<h1>Hello Spring</h1>
<p>회원기능</p>
<p>
<a href="/members/new">회원가입</a>
<a href="/members">회원목록</a>
</p>
</div>
</body>
</html>
<body>
<form action="/members/new" method="post">
<label for="name">이름</label>
<input type="text" id="name" name="name" placeholder="이름을 입력하세요.">
<button type="submit">등록</button>
</form>
</body>
public class MemberFormDTO {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<html xmlns:th="http://www.thymeleaf.org"><head>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div>
<table border="1">
<thead>
<tr>
<th>#</th>
<th>이름</th>
</tr>
</thead>
<tbody>
<tr th:each="member : ${members}">
<td th:text="${member.id}"></td>
<td th:text="${member.name}"></td>
</tr>
</tbody>
</table>
</div>
</body>
</html>
CREATE TABLE member(
id number(10) PRIMARY KEY,
name varchar2(600)
);
CREATE SEQUENCE member_seq
START WITH 1
INCREMENT BY 1;
INSERT INTO MEMBER VALUES (member_seq.nextval, 'spring');
SELECT * FROM MEMBER;
dependencies {
// 추가
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation group: 'com.oracle.database.jdbc', name: 'ojdbc6', version: '11.2.0.4'
}
#port
server.port=9090
#thymleaf cashe
spring.thymeleaf.cache=false
#encoding
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true
server.servlet.encoding.enabled=true
#dbms
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.username=myspring
spring.datasource.password=myspring