리눅스

 

 - 리눅스 기본 명령어

cafe.daum.net/flowlife/9A8Q/161

 

리눅스 기본 명령어

vmwarehttps://www.vmware.com/kr.html무료사용 제품VMware Workstation Playerhttps://www.centos.org/vmware에 centos 설치 하기https://jhnyang.tistory.com/280https://www.ubuntu-kr.org/1. 데비안(Debian)Debian은

cafe.daum.net

 - 리눅스 기본 편집기 vi/vim 명령어

inpages.tistory.com/124

 

 - 터미널 명령어 실행

pwd						: 사용자의 경로
ls						: 디렉토리
-l						: 자세히 보기
-a						: 숨김파일 확인
-al						: 숨김파일 자세히 보기
~						: 현재 사용자의 경로
/						: 리눅스의 경로
vi aaa					: 파일 생성
esc						: 입력어 대기화면
i, a					: append
shift + space			: 한영
:q!						: 미저장 종료
:wq						: 저장 후 종료
vi bbb.txt				: 파일 생성
리눅스에선 확장자 X
vi .ccc					: 숨김 파일 생성
.						: 숨김 파일
yy		  				: 복사
p 		  				: 붙여넣기
dd        				: 한줄 지우기
숫자+명령어   				: 명령어 여러번 반복
:set nu   				: 줄 번호 넣기
:set nonu 				: 줄 번호 제거
whoami    				: id 확인
s /home					: id 확인
mkdir kbs 				: 디렉토리 생성
mkdir -p  mbc/sbs 		: 상위 디렉토리 자동 생성
cd 디렉토리명 				: 디렉토리 변경
cd ~  					: home으로
cd .. 					: 상위 디렉토리로 이동
rmdir 디렉토리명   			: 디렉토리 삭제
rm 파일명         			: 파일 삭제
rm -rf kbs      		: 파일 있어도 삭제 가능
touch 파일명      			: 빈 파일 생성
cat 파일명        			: 파일 내용 확인
cat 파일명1 파일명2 			: 파일 내용확인
cp 파일명 디렉토리명/ 			: 파일 복사
cp 파일명 디렉토리명/새파일명 	: rename 파일 복사
mv 파일명 디렉토리        	: 파일 이동
rename 파일명 happy 새파일명 : 파일명 변경
mv 파일명 새파일명 			: 파일명 변경
head -3 파일명 			: 앞에 3줄 확인
tail -3 파일명 			: 뒤에 3줄 확인 
more +10 파일명 			: 
grep "검색어" 파일명 		: 검색
grep "[^A-Z]" 파일명* 		: 해당 파일명을 가진 모든 파일에서 대문자가 아닌 값 검색
whereis java 			: 파일 설치 모든 경로
whichis java 			: 파일 설치 경로
ifconfig				: ip 확인
su - root				: super user 접속
su - hadoop				: hadoop 일반 계정에 접속
useradd tom				: tom 일반 계정 만들기
passwd tom				: tom 일반 계정에 암호설정
exit					: 해당 계정 logout
userdel james			: 계정 삭제(logout상태에서)
rm -rf james			: 잔여 계정목록 삭제
-rwxrw-r--				: user, group, others
chmod u-w test.txt		: 현재 사용자에게 쓰기 권한 제거
chmod u-r test.txt		: 현재 사용자에게 읽기 권한 제거
chmod u+rwx test. extxt	: 현재 사용자에게 읽기/쓰기/excute 권한 추가
./test.txt				: 명령어 실행
chmod 777 test.txt		: 모든 권한 다 주기
chmod 111 test.txt		: excute 권한 다 주기
ls -l					: 목록 확인
rpm -qa					: 설치 목록확인
rpm -qa java*			: java 설치 경로
yum install gimp		: 설치
su -c 'yum install gimp': 설치
su -c 'yum remove gimp'	: 제거

 

 - gimp 설치

yum list gi*			: 특정단어가 들어간 리스트
which gimp				: gimp 설치 여부 확인
ls -a /usr/bin/gimp
yum info gimp			: 패키지 정보
gimp					: 실행
wget https://t1.daumcdn.net/daumtop_chanel/op/20200723055344399.png : 웹상에서 다운로드
wget https://archive.apache.org/dist/httpd/Announcement1.3.txt		: 웹상에서 다운로드

 

- 파일 압축

vi aa
gzip aa					: 압축
gzip -d aa.gz			: 압축해제
bzip2 aa				: 압축
bzip2 -d aa.bz2			: 압축해제
tar cvf	my.tar aa bb	: 파일 묶기
tar xvf my.tar			: 압축 해제
java -version			: 자바 버전 확인
su -					: 관리자 접속
yum update				: 패키지 업데이트
rpm -qa | grep java*	: rpm 사용하여 파일 설치
java					: 자바 실행
javac					: javac 실행
yum remove java-1.8.0-openjdk-headless.x86_64	: 삭제
yum -y install java-11-openjdk-devel			: 패키지 설치
rpm -qa | java			: 설치 확인

 

- 이클립스 다운로드

mkdir work				: 디렉토리 생성
cd work
eclipse.org - download - 탐색기 - 다운로드 - 복사 - work 붙여넣기
tar xvfz eclipse tab키	: 압축해제
cd eclipse/
./eclipse
work -> jsou
open spective - java
Gerneral - Workspace - utf-8
Web  - utf-8
file - new - java project - pro1 / javaSE-11 - Don't create
new - class - test / main
sysout alt /
sum inss

 

- FlashPlayer 설치

get.adobe.com/kr/flashplayer 접속

wget ftp://ftp.pbone.net/mirror/www.mde.djura.org/2007.0/RPMS/FlashPlayer-9.0.31.0-1mde2007.0.i586.rpm

rm -f FlashPlayer-9.0.31.0-1mde2007.0.i586.rpm

chmod 777 FlashPlayer-9.0.31.0-1mde2007.0.i586.rpm

rpm -Uvh --nodeps FlashPlayer*.rpm

 

- putty

putty -> ifconfig의 ip -> open -> 예

 

 - centos rpm

www.leafcats.com/171

 

 - CentOS에 MariaDB 설치

cafe.daum.net/flowlife/HqLk/81

 

 - MySql, MariaDB

cafe.daum.net/flowlife/HqLk/63 에서 다운로드
Build path - Configure Buil - Librarie - classpath - AddExternel JARs - apply

 

 - apache server 다운로드

apache.org 접속
맨아래 Tomcat 클릭
Download / Tomcat 10 클릭
tar.gz (pgp, sha512) 다운로드
터미널 창 접속
ls /~다운로드
cd work
mv ~/다운로드.apach ~~ .gz ./
tar xvfz apache-tomcat-10.0.5.tar.gz
cd apache-tomcat-10.0.5/
cd bin/
pwd
./startup.sh							: 서버 실행
http://localhost:8080/ 접속
./shutdown.sh							: 서버 종료
./catalina.sh run						: 개발자용 서버 실행
http://localhost:8080/ 접속
ctrl + c								: 개발자용 서버 종료
cd conf
ls se*
vi server.xml
cd ~
pwd
eclipse 접속
Dynimic web project 생성
이름 : webpro / Targert runtime -> apache 10 및 work - apache 폴더 연결
webapp에 abc.html 생성.
window - web browser - firefox
내용 작성 후 서버 실행.

 

 - R, R Studio Server 설치 및 기타

cafe.daum.net/flowlife/RlkF/11

 

 - R 설치

su - root
yum install epel-release
yum install dnf-plugins-core
yum config-manager --set-enabled powertools
yum install R
R
a <- 10
a
df <- data.frame(value=rnorm(1000, 1, 1))
head(df)
head(df, 3)
q()

 

 - R studio 설치

wget https://download1.rstudio.org/desktop/fedora28/x86_64/rstudio-1.2.5033-x86_64.rpm
rpm -ivh rstudio-1.2.5033-x86_64.rpm
exit
rstudio
install.packages("ggplot2")
library(ggplot2)
a <- 10
print(a)
print(head(iris, 3))
ggplot(data=iris, aes(x = Petal.Length, y = Petal.Width)) + geom_point()

 

 - R studio 서버

vi /etc/selinux/config
SELINUX=permissive으로 수정
reboot
su - root
vi /etc/selinux/config
cd /usr/lib/firewalld/services/
ls http*
cp http.xml R.xml
vi R.xml
port="8787"으로 수정
firewall-cmd --permanent --zone=public --add-service=R
firewall-cmd --reload
https://www.rstudio.com/products/rstudio/download-server/
redhat/centos
wget https://download2.rstudio.org/server/centos7/x86_64/rstudio-server-rhel-1.4.1106-x86_64.rpm
wget https://download2.rstudio.org/server/fedora28/x86_64/rstudio-server-rhel-1.2.5033-x86_64.rpm

yum install --nogpgcheck rstudio-server-rhel-1.4.1106-x86_64.rpm
systemctl status rstudio-server
systemctl start rstudio-server
http://ip addr:8787/auth-sign-in	: 본인 ip에 접속

useradd testuser
passwd testuser
ls /home

mkdir mbc
cd mbc
ls

 

 - 프로그램 셋팅 : ipython, anaconda

cafe.daum.net/flowlife/RUrO/44

주의 : VmWare를 사용할 때는 Virtual Machine Settings에서 Processors를 2 이상으로 주도록 하자. 

 

- anaconda 설치

www.anaconda.com/products/individual

Download - Linux / 64-Bit (x86) Installer (529 MB) - 링크주소 복사

wget https://repo.anaconda.com/archive/Anaconda3-2020.02-Linux-x86_64.sh
chmod +x Anaconda~~
./Anaconda~~
q
yes
vi .bash_profile		: 파일 수정
=============================================
PATH=$PATH:$HOME/bin
export PATH

# added by Anaconda3 installer
export PATH="/home/hadoop/anaconda3/bin:$PATH"
==============================================
source .bash_profile
python3
conda deactivate     : 가상환경 나오기
source activate base : 가상환경 들어가기
jupyter notebook
jupyter lab
localhost:8888/tree
ctrl + c
y
jupyter notebook --generate-config
python
from notebook.auth import passwd
passwd()     #sha1 값 얻기
quit()
비밀번호 설정
Verify password 복사
vi .jupyter/jupyter_notebook_config.py		: 파일 수정
ctrl + end
==============================================
c.NotebookApp.password =u'       Verify password 붙여넣기		'
==============================================
quit()
vi .jupyter/jupyter_notebook_config.py
su -
cd /usr/lib/firewalld/services/
cp http.xml NoteBook.xml
vi NoteBook.xml
8001포트 설정
:wq
systemctl status firewalld.service           방화벽 서비스 상태 확인  start, stop, enable
firewall-cmd --permanent --zone=public --add-service=NoteBook
firewall-cmd --reload 
jupyter notebook --ip=0.0.0.0 --port=8001 --allow-root
jupyter lab --ip=0.0.0.0 --port=8001 --allow-root
vi .jupyter/jupyter_notebook_config.py
==============================================
c.NotebookApp.open_browser = False
==============================================

 

 - 하둡 ppt

cafe.daum.net/flowlife/RZ23/24

 : 빅데이터 파일을 여러 대의 서버에 분산 저장(HDFS, Hadoop Distributed File Syetem).

 : 각 서버에서 분산병렬 처리.(MapReduce)

 : 하둡은 데이터 수정불가.

 : sale-out 사용.

 

 - Hadoop 싱글노드로 설치 : Centos 기반 (2020년 기준)

cafe.daum.net/flowlife/RZ23/11

 

 - 하둡 설치

conda deactivate	: 가상환경 나오기
java -version		: 자바 버전 확인
ls -al /etc/alternatives/java	: 자바 경로 확인 후 경로 복사
 => /usr/ ~~ .x86_64 복사
https://apache.org/ 접속 => 맨 밑에 hadoop접속 => Download => 
su -				: 관리자 접속
cd /usr/lib/firewalld/services/	: 특정 port 방화벽 해제
cp http.xml hadoop.xml
vi hadoop.xml					: 파일 수정 후 저장(:wq)
==============================================
<?xml version="1.0" encoding="utf-8"?>
<service>
    <short>Hadoop</short>
    <description></description>
    <port protocol="tcp" port="8042"/>    
    <port protocol="tcp" port="9864"/>
    <port protocol="tcp" port="9870"/>
    <port protocol="tcp" port="8088"/>
    <port protocol="tcp" port="19888"/>
</service>
==============================================
firewall-cmd --permanent --zone=public --add-service=hadoop
firewall-cmd --reload
exit
wget http://apache.mirror.cdnetworks.com/hadoop/common/hadoop-3.2.1/hadoop-3.2.1.tar.gz
tar xvzf hadoop-3.2.1.tar.gz
vi .bash_profile
==============================================
# User specific environment and startup programs
export JAVA_HOME=/usr/ ~~ .x86_64 붙여넣기
export HADOOP_HOME=/home/사용자명/hadoop-3.2.1     
PATH=$PATH:$HOME/.local/bin:$HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin  #추가
export PATH
==============================================
source .bash_profile		: .bash_profile을 수정된 내용으로 등록
conda deactivate
ls
cd hadoop-3.2.1/
vi README.txt
vi kor.txt					: 임의 내용 입력
cd etc
cd hadoop
pwd
vi hadoop-env.sh			: 파일 상단에 입력
==============================================
export JAVA_HOME=/usr/ ~~ .x86_64 붙여넣기
==============================================

vi core-site.xml        : 하둡 공통 설정을 기술
==============================================
<configuration>
        <property>
                <name>fs.default.name</name>
                <value>hdfs://localhost:9000</value>
        </property>
      <property>
                 <name>hadoop.tmp.dir</name> 
                       <value>/home/사용자명/hadoop-3.2.1/tmp/</value>
            </property>
</configuration>
==============================================

vi hdfs-site.xml      : HDFS 동작에 관한 설정
==============================================
<configuration>
     <property>
          <name>dfs.replication</name>
          <value>1</value>
     </property>
</configuration>
==============================================

vi yarn-env.sh         : yarn 설정 파일
==============================================
export JAVA_HOME=/usr/ ~~ .x86_64 붙여넣기
==============================================

vi mapred-site.xml      : yarn 설정 파일
==============================================
<configuration>
     <property>
          <name>mapreduce.framework.name</name>
          <value>yarn</value>
     </property>
     <property>
        <name>mapreduce.admin.user.env</name>
        <value>HADOOP_MAPRED_HOME=$HADOOP_COMMON_HOME</value>
    </property>
    <property>
        <name>yarn.app.mapreduce.am.env</name>
        <value>HADOOP_MAPRED_HOME=$HADOOP_COMMON_HOME</value>
    </property>
</configuration>
==============================================

vi yarn-site.xml
==============================================
<configuration>
<!-- Site specific YARN configuration properties -->
     <property>
          <name>yarn.nodemanager.aux-services</name>
          <value>mapreduce_shuffle</value>
     </property>
     <property>
          <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
          <value>org.apache.hadoop.mapred.ShuffleHandler</value>
     </property>
</configuration>
==============================================

cd					: root로 이동
hdfs namenode -format
hadoop version		: 하둡 버전 확인

ssh					: 원격지 시스템에 접근하여 암호화된 메시지를 전송할 수 있는 프로그램
ssh-keygen -t rsa	: ssh 키 생성. enter 3번.
cd .ssh
scp id_rsa.pub /home/사용자명/.ssh/authorized_keys	: 생성키를 접속할 때 사용하도록 복사함. yes
ssh 사용자명@localhost

start-all.sh		: deprecated
start-dfs.sh
start-yarn.sh
mr-jobhistory-daemon.sh start historyserver	: 안해도됨

jps					: 하둡 실행 상태 확인 - NameNode와 DataNode의 동작여부 확인

stop-all.sh			: deprecated
stop-dfs.sh
stop-yarn.sh

 

http://localhost:9870/ 접속 : Summary(HDFS 상태 확인)
http://localhost:8088/ 접속 : All Applications

 

 - Map/Reduce 처리과정

cafe.daum.net/flowlife/RZ23/17

 

 - 워드 카운트

conda deactivate
cd hadoop-3.2.1/
hdfs dfs -mkdir /test
hdfs dfs -ls/test
hdfs dfs -copyFromLocal ./README.txt /test	: 복사
hdfs dfs -cat /test/README.txt
hadoop jar /home/사용자명/hadoop-3.2.1/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.1.jar wordcount /test/README.txt /output			: map/reduce 작업 진행.
hdfs dfs -ls /output						: 목록확인
hdfs dfs -cat /output/part-r-00000
hdfs dfs -ls /
hdfs dfs -rm /output/part*					: 파일삭제
hdfs dfs -rm /output/_SUCCESS
hdfs dfs -rmdir /output

hdfs dfs -put ./kor.txt /test
hadoop jar /home/사용자명/hadoop-3.2.1/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.1.jar wordcount /test/kor.txt /daumdata
hdfs dfs -get /daumdata/part* happy.txt		: 하둡에서 파일 가져오기
ls
vi happy.txt

 

 - eclipse + hadoop 연동

conda deactivate
start-dfs.sh
start-yarn.sh
jps
http://localhost:9870/ 접속	: Summary(HDFS 상태 확인)
http://localhost:8088/ 접속	: All Applications
eclipse 실행

 

Tensorflow.js 간단한 예

cafe.daum.net/flowlife/S2Ul/27

 

 * abc.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>tensorflow.js sample</title>
    <script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js"></script>

    <script type="text/javascript">
    function abc(){
        // 선형회귀 모델 생성
        const model = tf.sequential();
        model.add(tf.layers.dense({units: 1, inputShape: [1]}));
 
        // 학습을 위한 준비 : 손실 함수와 최적화 함수를 설정
        model.compile({loss: 'meanSquaredError', optimizer: 'sgd'});
 
        // 학습 데이터
        const xs = tf.tensor2d([1, 2, 3, 4], [4, 1]);
        const ys = tf.tensor2d([1, 3, 5, 7], [4, 1]);
 
        // 데이터를 사용해서 학습
        model.fit(xs, ys).then(() => {
            // 학습된 모델로 결과 예측값 얻기
            pred = model.predict(tf.tensor2d([5], [1, 1]))
            pred.print()    // console로 출력
  document.write('예측값 : ', pred);
        });
    }
    </script>	
</head>
<body>
    결과는 브라우저의 콘솔로 확인하세요.
   <br>
    <button xxxxxxxxxxxxonclick="abc()">클릭</button>
</body>
</html>

 

propertive - javaSE
프로젝트 생성
hadoop_pro
Java1.8
프로젝트 오른쪽 클릭
Configure - Convert to Maven Project

 

* pom.xml

maven.org

hadoop-common 검색
apache
3.2.1
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-common</artifactId>
  <version>3.2.1</version>
</dependency>

hadoop-client
apache
3.2.1
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-client</artifactId>
  <version>3.2.1</version>
</dependency>

hadoop-hdfs
apache
3.2.1
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-hdfs</artifactId>
  <version>3.2.2</version>
</dependency>

hadoop-mapreduce-client-core
apache
3.2.1
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-mapreduce-client-core</artifactId>
  <version>3.2.2</version>
</dependency>

 

 - example code download

hadoop.apache.org/

Documentation - 3.2.2

MapReduce
Tutorial
Example: WordCount v1.0 - Source Code

 

src - new - class - pack.WordCount

* WordCount.java

import java.io.IOException;
import java.util.StringTokenizer;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

public class WordCount {

  public static class TokenizerMapper
       extends Mapper<Object, Text, Text, IntWritable>{

    private final static IntWritable one = new IntWritable(1);
    private Text word = new Text();

    public void map(Object key, Text value, Context context
                    ) throws IOException, InterruptedException {
      StringTokenizer itr = new StringTokenizer(value.toString());
      while (itr.hasMoreTokens()) {
        word.set(itr.nextToken());
        context.write(word, one);
      }
    }
  }

  public static class IntSumReducer
       extends Reducer<Text,IntWritable,Text,IntWritable> {
    private IntWritable result = new IntWritable();

    public void reduce(Text key, Iterable<IntWritable> values,
                       Context context
                       ) throws IOException, InterruptedException {
      int sum = 0;
      for (IntWritable val : values) {
        sum += val.get();
      }
      result.set(sum);
      context.write(key, result);
    }
  }

  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
	
	conf.set("fs.default.name", "hdfs://localhost:9000");
	
    Job job = Job.getInstance(conf, "word count");
    job.setJarByClass(WordCount.class);
    job.setMapperClass(TokenizerMapper.class);
    job.setCombinerClass(IntSumReducer.class);
    job.setReducerClass(IntSumReducer.class);
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
	
    FileInputFormat.addInputPath(job, new Path("hdfs://localhost:9000/test/data.txt"));
    FileOutputFormat.setOutputPath(job, new Path("hdfs://localhost:9000/out1"));
	System.out.println("success");
	
    //FileInputFormat.addInputPath(job, new Path(args[0]));
    //FileOutputFormat.setOutputPath(job, new Path(args[1]));
	
	System.exit(job.waitForCompletion(true) ? 0 : 1);
  }
}
ls
cd hadoop-3.2.1/
vi data.txt
임의 텍스트 입력
hdfs dfs -put data.txt /test
hdfs dfs -get /out1/part* result1.txt
vi result1.txt
vi vote.txt
임의 텍스트 입력
hdfs dfs -put vote.txt /test

src - new - class - pack2.VoteMapper

 

 * VoteMapper.java

import java.util.regex.*;
import org.apache.hadoop.io.IntWritable
import org.apache.hadoop.io.Text
import org.apache.hadoop.mapreduce.Mapper


public class VoteMapper extends Mapper<Object, Text, Text, IntWritable>{
	private final static IntWritable one =  new IntWritable(1);
	private Text word = new Text();
	
	@Override
	public void map(Object ket, Text value, Context context)throws IOException, InterruptedException{
		String str = value.toString();
		System.out.println(str);
		String regex = "홍길동|신기해|한국인";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		String result = "";
		while(match.find()){
			result += matcher.group() + "";
		}
		StringTokenizer itr = new StringTokenizer(result);
		
		while(itr.hasMoreTokens()){
			word.set(itr.nextToken());
			context.write(word, one);
		}
	}
}

 

src - new - class - pack2.VoteReducer

 

 * VoteReducer.java

public class VoteReducer extends Reducer<Textm IntWritable, Text, IntWritable>{
	private IntWritable result = new IntWritable();
	
	@Override
	public void reduce(Text key, Iterable<IntWritable> values, Context context) throw IOException, InterruptedException{
		int sum = 0;
		for(IntWritable val:values){
			sum += val.get();
		}
		
		result.set(sum);
		context.wrtie(key, result);
	}
}

 

src - new - class - pack2.VoteCount

 

 * VoteCount.java

public class VoteCount{
	public static void main(String[] args) throws Exception{
		Configuration conf = new Configuration();
		conf.set("fs.default.name", "hdfs://localhost:9000");
		
		Job job = Job.getInstance(conf, "vote");
		job.setJarByClass(VoteCount.class);
		job.setMapperClass(VoteMapper.class);
		job.setCombinerClass(VoteReducer.class);
		job.setReducerClass(VoteReducer.class);
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);
		
		FileInputFormat.addInputPath(job, new Path("hdfs://localhost:9000/test/vote.txt"));
		FileOutputFormat.setOutputPath(job, new Path("hdfs://localhost:9000/out2"));
		
		System.out.println("end");
		
		System.exit(job.waitForCompletion(true)?0:1);
	}
}

 

hdfs dfs -get /out2/part* result2.txt

'BACK END > Python Library' 카테고리의 다른 글

[Pandas] pandas 정리2 - db, django  (0) 2021.03.02
[MatPlotLib] matplotlib 정리  (0) 2021.03.02
[Pandas] pandas 정리  (0) 2021.02.24
[NumPy] numpy 정리  (0) 2021.02.23

11. Ajax

12. Ajax + DB

13. Join

 


11. Ajax

 : ajax 송부한 데이터에 문자열 더하여 수신 받기.

 : ajax 요청하여 수신 받은 데이터 출력하기.

 

 = django_test10_ajax

 * settings

INSTALLED_APPS = [
    
    ...
    
    'myajaxapp',
]

 => application 연결

 

 * urls

from django.contrib import admin
from django.urls import path
from myajaxapp import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.indexFunc),
    path('startajax', views.func1),
    path('goajax', views.func2),
]

 => url -> function 연결

     url '' -> indexFunc

     url 'startajax' -> func1

     url 'goajax' -> func2

 

 

 * views

from django.shortcuts import render
import json
from django.http.response import HttpResponse

lan = {
    'id':111,
    'name':'파이썬',
    'history':[
        {'date':'2021-2-12','exam':'basic'},
        {'date':'2021-2-22','exam':'django'},
    ]
}

def test(): # json encoding/decoding
    print(type(lan)) # dict
    jsonString  = json.dumps(lan)
    jsonString  = json.dumps(lan, indent = 4) # 들어쓰기
    print(jsonString)
    #{"id": 111, "name": "\ud30c\uc774\uc36c", 
    #"history": [{"date": "2021-2-12", "exam": "basic"}, {"date": "2021-2-22", "exam": "django"}]}
    print(type(jsonString)) # str
    
    print('----------------------------------------------------------')
    
    dic = json.loads(jsonString)
    print(dic)
    print(type(dic)) # dict
    print(dic['name'])
    for h in dic['history']:
        print(h['date'], h['exam'])
    #2021-2-12 basic
    #2021-2-22 django
    
def indexFunc(request):
    test()
    return render(request,'abc.html')
	
    ...

 => import jason

 => json.dumps(data, indent = 들여쓰기) : json encoding. python object(Dict, List, Tuple..)를 문자열로 변경하는 작업

 => json.loads(data) : json decoding. 문자열을 python object(Dict, List, Tuple..)로 변경하는 작업

 => indexFunc() -> abc.html

 

 * abc.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function(){
	$("#btn1").click(function(){
		let msg = $("#txtMsg").val()
		$("#showData").empty();
		$.ajax({
			url:'startajax',
			type:'get',
			data:{'msg':msg}, /* msg=msg */
			dataType:'json',
			success:function(data){
				let str = '';
				for(let k in data){
					let str = k + '<br>' + data[k];
				}
				str += "<br><b>"+data['key']+"</b>";
				$("#showData").html(str);
			},
			error:function(){
				$("#showData").text("에러");
			}
		});
	});
	
	$("#btn2").click(function(){
		//$("#showData2").text("<i>1</i>"); // <i> 그대로 출력
		$("#showData2").html("<i>1</i>");
		$.ajax({
			url:'goajax',
			type:'get',
			dataType:'json',
			success:function(data){
				//alert(data);
				let str = '';
				$.each(data, function(ind, entry){ //jquery 반복문
					str += entry['name'] + ', ' + entry['age'] + '<br>';
				});
				$("#showData2").html(str);
			},
			error:function(){
				$("#showData2").text("에러");
			}
		});
	});
});
</script>
</head>
<body>
<h2>Ajax test</h2>
자료입력 : <input type="text" id="txtMsg" value="홍길동">
<button id="btn1">버튼1 클릭</button>
<br>
<div id="showData">실습결과1</div>
<hr>
<button id="btn2">버튼2 클릭</button>
<br>
<div id="showData2">실습결과2</div>
</body>
</html>

$.ajax({

    url:'요청명',

    type:'get/post',

    dataType:'json',

    success:function(x){

        // 성공 시 실행문

    }

    error:function(){

        // 에러 발생 시 실행문

    }

});

=> ajax 처리

 

$.each(x, function(idx, entry){

    // for entry in x: 과 동일

    // 반복문

});

 => json 반복문

 * views

...

import time
def func1(request):
    msg = request.GET['msg']
    #print(msg) # 홍길동
    time.sleep(1);
    context = {'key':msg + ' ajax 요청 처리'} # dict - 홍길동 ajax 요청 처리
    return HttpResponse(json.dumps(context), content_type="application/json") # dict -> str

def func2(request):
    datas = [
        {'name' : '고길동', 'age':25},
        {'name' : '김길동', 'age':27},
        {'name' : '나길동', 'age':28},
    ]
    return HttpResponse(json.dumps(datas), content_type="application/json")

 => request.GET['msg'] : 요청의 'msg' key의 값을 get.

 => HttpResponse(json.dumps(context), content_type="application/json") : context를 dict 타입에서 str로 변환 후

       json형식의 str을 send.


12. Ajax + DB

 : ajax 요청 시 DB의 직원 테이블 data 조회하여 출력하기.

 

 = django_test11_ajax

 => create application - myajax

 

 * settings

...

INSTALLED_APPS = [
    
    ...
    
    'myajax',
]

...

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'test',                # DB명 : db는 미리 작성되어 있어야 함.       
        'USER': 'root',                # 계정명 
        'PASSWORD': '123',             # 계정 암호           
        'HOST': '127.0.0.1',           # DB가 설치된 컴의 ip          
        'PORT': '3306',                # DBMS의 port 번호     
    }
}

...

 => application 연결.

 => DB 설정

 

 

 * anaconda prompt

cd C:\work\psou\django_test11_ajax
python manage.py inspectdb > aaa.py

 

 

 * models

from django.db import models

# Create your models here.
class Sangdata(models.Model):
    code = models.IntegerField(primary_key=True)
    sang = models.CharField(max_length=20, blank=True, null=True)
    su = models.IntegerField(blank=True, null=True)
    dan = models.IntegerField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'sangdata'

 => aaa.py의 사용할 table을 models.py에 복사 붙여넣기. (제작된 Table을 Django 형식으로 자동 생성)

 

 Make migrations - myajax

 Migrate

 

 

 * urls

from django.contrib import admin
from django.urls import path
from myajax import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.MainFunc),
    path('list', views.ListFunc),
    path('calldb', views.ListDbFunc),
]

 => url -> function 연결.

 => url '' -> MainFunc()

 => url 'list' -> ListFunc()

 => url 'calldb' -> ListDbFunc()

 

 

 * views

from django.shortcuts import render
from myajax.models import Sangdata
from django.http.response import HttpResponse
import json

# Create your views here.
def MainFunc(request):
    return render(request, 'main.html')

def ListFunc(request):
    return render(request, 'list.html')

def ListDbFunc(request):
    sdata = Sangdata.objects.all() # db sangdata 전체 읽기
    datas = []
    for s in sdata:
        #print(s.code)
        dict ={'code':s.code, 'sang':s.sang, 'su':s.su,'dan':s.dan}
        datas.append(dict)
    #print(datas)
    #[{'code': 1, 'sang': '장갑', 'su': 3, 'dan': 10000},
    # {'code': 2, 'sang': '벙어리장갑', 'su': 2, 'dan': 12000},
    # {'code': 3, 'sang': '가죽장갑', 'su': 10, 'dan': 50000}, 
    # {'code': 4, 'sang': '가죽점퍼', 'su': 5, 'dan': 650000}, 
    # {'code': 6, 'sang': '신상', 'su': 11, 'dan': 3000}, 
    # {'code': 7, 'sang': '아메리카노', 'su': 2, 'dan': 1}, 
    # {'code': 8, 'sang': '가방', 'su': 22, 'dan': 300}]
    return HttpResponse(json.dumps(datas), content_type='application/json')

 => MainFunc() -> main.html

 => ListFunc() -> list.html

 => ListDbFunc() : db data 읽은 후 json data send.(dict -> list -> str로 변환)

 

 

 * main.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>메인</h2>
<a href="/list">상품 보기</a>
</body>
</html>

 

 * list.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-latest.js"></script>

<script type="text/javascript">
$(document).ready(function(){
	$("#btnOk").click(function(){
		$("#showData").empty();
		
		$.ajax({
			url:'calldb',
			type:'get',
			dataType:'json',
			success:function(data){
				//alert(data);
				let str = "<table border='1'>";
				str += "<tr><th>코드</th><th>상품명</th><th>수량</th><th>단가</th></tr>";
				let count = 0;
				$.each(data, function(ind, entry){
					str += "<tr>";
					str += "<td>" + entry['code'] + "</td>";
					str += "<td>" + entry['sang'] + "</td>";
					str += "<td>" + entry['su'] + "</td>";
					str += "<td>" + entry['dan'] + "</td>";
					str += "</tr>";
					count += 1;
				});
				
				str += "</table>";
				$("#showData").append(str);
				$("#showData").append("건수 : "+count);
			},
			errorLfunction(){
				$("#showData").text("로딩 실패");
			}
		});
	});
});
</script>

</head>
<body>
<h2>상품 목록</h2>
<button id="btnOk">상품자료 출력(Ajax)</button><br><br>
<div id="showData"></div>
<hr>
</body>
</html>

 => button click 시 ajax로 'calldb' 요청명 send 후 성공 시 table 형태로 조회된 DB 데이터 출력.


13. Join

 * views

SearchJikwonFunc(request):
    jikwon_jik = request.GET["jikwon_jik"]
    jikwonList = Jikwon.objects.extra(select={'buser_name':'buser_name'}, tables=['Buser'],
    where =['Buser.buser_no=Jikwon.buser_num']).filter(jikwon_jik = jikwon_jik)
    data = []
    for j in jikwonList:
        dict ={}
        dict['jikwon_no'] = j.jikwon_no
        dict['jikwon_name'] = j.jikwon_name
        dict['buser_name'] = j.buser_name
        data.append(dict)
    print(data)
    return HttpResponse(json.dumps(data), content_type = "application/json")

 

Python 정리 (내용을 클릭하세요)
1. 변수 2. 연산자 3. 집합형 자료 4. 정규 표현식 5. 조건 판단문 if
6. 반복문 while 7. 반복문 for 8. 함수 9. 변수의 생존 범위 10. closure(클로저)
11. 일급함수 12. Module 13. 사용자 정의 모듈 14. turtle 15. 외부 모듈 사용
16. Class 17. 포함관계 (has a) 18. 상속 19. 메소드 오버라이딩 20. 다중 상속
21. 추상클래스 22. 예외처리 23. file i/o 24. wxPython 25. SQLite
26.  DB 연동 27. socket 28. Thread 29. multi thread chat 30. pool
31. process 32. 웹 크롤링(crawling) 33. HttpServer 34. CGI 35. 챗봇(chatbot)

 

1. web scraping : 한 페이지를 가져옴

install.packages("XML")   # install.packages() : XML 라이브러리 설치
install.packages("httr")  # httr 라이브러리 설치
library(XML)              # library() : 라이브러리 불러오기. pakages tab에서 확인가능
library(httr)             # 라이브러리 불러오기

source <- htmlParse(rawToChar(GET("https://www.melon.com/song/popup/lyricPrint.htm?songId=10000")$content))
# 웹페이지의 전체 html문을 가져온다.

lyrics <- xpathSApply(source, "//div[@class='box_lyric_text']", xmlValue)
# source에서 div의 값을 가져온다.

lyrics <-gsub("[\r\n\t]","",lyrics) # gsub(a,b,c) : c에서 a의 내용을 b로 변경.

 

2. RDMS의 자료 읽기

 - 내장 데이터 베이스 : SQLite

install.packages("rJava")
install.packages("DBI")
install.packages("RJDBC")
install.packages("RSQLite")
library(rJava)
library(DBI)
library(RJDBC)
library(RSQLite)

conn <- dbConnect(RSQLite::SQLite(), ":memory:") # memory : 데이터가 ram상에만 존재
head(mtcars, 3)                                  #default dataset 중 하나
# mpg cyl disp  hp drat    wt  qsec vs am gear carb
# Mazda RX4     21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
# Mazda RX4 Wag 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
# Datsun 710    22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
colnames(mtcars)

dbWriteTable(conn, "mtcars", mtcars)    # mtcar 테이블 가져오기
dbListTables(conn)                      # 연결 객체의 테이블 확인 - mtcars
dbListFields(conn,"mtcars")             # 변수 확인

query <- "select * from mtcars"
goodAll <- dbGetQuery(conn, query)      # query 문 실행.
goodAll2 <- dbGetQuery(conn, "select mpg, cyl, disp from mtcars where mpg >= 30")

dbDisconnect(conn)                      # db 객체연결 객체해제

 

 - 원격 DB : sangdata

drv <- JDBC(driverClass = "org.mariadb.jdbc.Driver", classPath = "D:/1. 프로그래밍/0. 설치 Program/mariaDB/mariadb-java-client-2.6.2.jar")
conn <- dbConnect(drv, "jdbc:mysql://127.0.0.1:3306/test","root","123")
conn
dbListTables(conn)

query <- "select * from sangdata"
sangDatas <- dbGetQuery(conn, query)
sangDatas
class(sangDatas) #  data.frame
dim(sangDatas)
nrow(sangDatas)
sangDatas[1:3,]
sangDatas$sang

sangs <- dbGetQuery(conn, "select * from sangdata where sang like '가죽%'")
sangs

# 자료 추가
query <- "insert into sangdata values(10,'신상1', 3, 3500)"
dbSendUpdate(conn, query)           # insert문 실행

df <- data.frame(code =11, sang='볼펜', su=7, dan=2000)
df
dbSendUpdate(conn, "insert into sangdata values(?,?,?,?)", df$code, df$sang, df$su, df$dan)
dbGetQuery(conn, "select * from sangdata")

# 자료 수정
query <- "update sangdata set sang=? where code=11"
dbSendUpdate(conn, query, "컴퓨터") # update문 실행
dbGetQuery(conn, "select * from sangdata")


# 자료 삭제
dbSendUpdate(conn, "delete from sangdata where code =10") # delete문 실행
dbGetQuery(conn, "select * from sangdata")

 

[목차]

5. AOP (Aspect Oriented Program)

* 스프링 AOP에서 용어
① AOP 구현

 


 

[내용]

5. AOP (Aspect Oriented Program)

 

: 핵심 로직에서 임의의 동작을 진행할 경우 사용. 
: 별도의 클래스로 정의하여 메소드를 탈부착식으로 사용한다.

: ex) 시큐리티, 로그인, 트랜잭션

 

 1) 설정

 ⓛ 사이트 접속 - search.maven.org/

 ② search창에 aspectjweaver 검색

 ③ version 선택

 ④ Apache Maven 내용 copy & paste

 ⑤ search창에 cglib 검색

 ⑥ version 선택

 ⑦ Apache Maven 내용 copy & paste

 ⑧ pom.xml에 Code 추가

<!-- aop -->
<dependencies>
	<dependency>
		<groupId>aspectj</groupId>
		<artifactId>aspectjweaver</artifactId>
		<version>1.5.4</version>
	</dependency>
	<dependency>
		<groupId>cglib</groupId>
		<artifactId>cglib</artifactId>
		<version>3.3.0</version>
	</dependency>
</dependencies>

 ⑨ 경로에 생성됨. C:\Users\wonh\.m2\repository\

 

2) code

- HelloInter

public interface HelloInter {
	void hello();
	void hi();	
}

 - HelloInterImpl

public class HelloInterImpl implements HelloInter{
	
	public HelloInterImpl() {
		System.out.println("HelloInterImpl 생성자");
	}
	
	public void hello() {
		System.out.println("hello 처리");
	}

	public void hi() {
		System.out.println("hi 처리");
	}
}

 - WriteInter

public interface WriteInter {
	void write();
}

 - WriteInterImpl

public class WriteInterImpl implements WriteInter{ // 핵심 로직을 가진 클래스
	
	public WriteInterImpl() {
		System.out.println("WriteInterImpl 생성자");
	}

	public void write() {
		System.out.println("write 수행");
	}
}

 - MyAspect

public class MyAspect { // 관심사항을 가진 클래스
	public void myLogOn() {
		System.out.println("핵심 메소드 수행전 로그온 작업");
	}
	
	public void myLogOut() {
		System.out.println("핵심 메소드 수행후 로그아웃 작업");
	}
	
	public void mySecurity() {
		System.out.println("핵심 메소드 수행전 보안설정");
	}
}

 - AspectProcess

public class AspectProcess { // 여러개의 관심사항들을 모아 처리하는 클래스
	private MyAspect myAspect; // 관심사항 클래스. 여러개 가능
	
	public void setMyAspect(MyAspect myAspect) {
		this.myAspect = myAspect;
	}
	
	public Object logging(ProceedingJoinPoint joinPoint) throws Throwable{
		Object object = null;
		
		myAspect.myLogOn();
		object = joinPoint.proceed(); // 메타파일에서 설정한 핵심 메소드 수행.
		myAspect.myLogOut();
		
		return object;
	}
	
	public Object logging2(ProceedingJoinPoint joinPoint) throws Throwable{
		Object object = null;
		
		myAspect.mySecurity();
		object = joinPoint.proceed(); // 메타파일에서 설정한 핵심 메소드 수행.
		return object;
	}
}

 => logging() 메소드는 myLogOn() -> 핵심로직 -> myLogOut() 순 호출

 => logging2() 메소드는 mySecurity() -> 핵심로직 순 호출

 - main

public static void main(String[] args) {
	//String[] configs = new String[] {"aop1core.xml"}; // 핵심만 수행
	String[] configs = new String[] {"aop1core.xml", "aop1.xml"}; // 핵심 + Aop 수행.
	
	ApplicationContext context = new ClassPathXmlApplicationContext(configs);
	
	WriteInter writeInter = (WriteInter)context.getBean("writeInterImpl");
	writeInter.write();
	System.out.println();
	
	HelloInterImpl helloInter = (HelloInterImpl)context.getBean("helloInterImpl"); // 방법 1
	HelloInter helloInter = context.getBean("helloInterImpl", HelloInter.class); // 방법 2
	helloInter.hi();
	helloInter.hello();
}

 - aop1core.xml

<bean id="writeInterImpl" class="aop1.WriteInterImpl"/>
<bean id="helloInterImpl" class="aop1.HelloInterImpl"/>

 - aop1.xml

<!-- Aspect(Advice) -->
<bean id="aspectProcess" class="aop1.AspectProcess">
	<property name="myAspect" ref="myAspect"/>
</bean>
<bean id="myAspect" class="aop1.MyAspect"/>

<!-- Aop 설정 -->
<aop:config>
	<aop:pointcut expression="execution(public void wri*(..))" id="poi1"/>
	// wri로 시작하고 매개변수가 0개 이상인 메소드
	// <aop:pointcut expression="execution(public void write())" id="poi1"/>
	<aop:aspect ref="aspectProcess">
		<aop:around method="logging" pointcut-ref="poi1"/>
	</aop:aspect>
</aop:config>
<aop:config>
	<aop:pointcut expression="execution(public void hel*(..)) or execution(public void hi*(..))" id="poi2"/>
	// or || and &&
	<aop:aspect ref="aspectProcess">
		<aop:around method="logging2" pointcut-ref="poi2"/>
	</aop:aspect>
</aop:config>

 => 핵심 로직의 wri로 시작하고 메개변수가 0개 이상인 메소드가 호출될때 AspectProcess(Aspect를 처리하는) 클래스의 logging() 메소드가 실행된다.

 => 핵심 로직의 hel로 시작하고 메개변수가 0개 이상인 메소드 또는 hi로 시작하는 메소드가 호출될때 AspectProcess클래스의 logging2() 메소드가 실행된다.

 


 - ArticleInter

public interface ArticleInter {
	void select();
}

 

- ArticleDao

//@Component
//@Repository
@Repository("articleDao")

public class ArticleDao implements ArticleInter{

	public void select() {
		System.out.println("db의 상품 자료를 read");
	}
}

 - LogicInter

public interface LogicInter {
	void selectData_process();
}

 - LogicImpl

public class LogicImpl implements LogicInter{
	private ArticleInter articleInter; 
    
	public LogicImpl() {
	}
	
	public LogicImpl(ArticleInter articleInter) {
		this.articleInter = articleInter; 
	}
	
	public void selectData_process() {
		System.out.println("selectData_proces 수행");
		articleInter.select();
	}
}
@Service
public class LogicImpl implements LogicInter{

	@Autowired
	//@Qualifier("aticleDao")
	private ArticleInter articleInter; 
	
	public void selectData_process() {
		System.out.println("selectData_proces 수행");
		articleInter.select();
	}
}

 

 - ProfileAdvice

public class ProfileAdvice { // Advice, Aspect
	public Object abc(ProceedingJoinPoint joinPoint) throws Throwable{
		//핵심 메소드 이름 얻기
		String methodName = joinPoint.getSignature().toString();
		
		System.out.println(methodName+" 시작 전 작업");
		Object object = joinPoint.proceed(); // 핵심 메소드
		System.out.println(methodName+" 처리 후 작업");
		
		return object;
	}
}
@Aspect
@Component
public class ProfileAdvice { // Advice, Aspect
	@Around("execution(public void selectData_process())")
	public Object abc(ProceedingJoinPoint joinPoint) throws Throwable{
		//핵심 메소드 이름 얻기
		String methodName = joinPoint.getSignature().toString();
		
		System.out.println(methodName+" 시작 전 작업");
		Object object = joinPoint.proceed(); // 핵심 메소드
		System.out.println(methodName+" 처리 후 작업");
		
		return object;
	}
}

 

 - main

public static void main(String[] args) {
	ApplicationContext context = new ClassPathXmlApplicationContext("aop2.xml");
	LogicInter inter = (LogicInter)context.getBean("logicImpl");
	inter.selectData_process();
}

 - aop2.xml

<!-- 핵심 로직 처리용 클래스 -->
<bean id="logicImpl" class="aop2.LogicImpl">
	<constructor-arg>
		<ref bean="articleDao"/>
	</constructor-arg>
</bean>
<bean id="articleDao" class="aop2.ArticleDao"></bean>

<!-- Aop 설정 -->
<bean id="profileAdvice" class="aop2.ProfileAdvice"/>
<aop:config>
	<aop:aspect ref="profileAdvice">
		<aop:pointcut expression="execution(public void selectData_process())" id="poi"/>
		<aop:around method="abc" pointcut-ref="poi"/>
	</aop:aspect>
</aop:config>	

 => 핵심로직의 selectData_process()메소드 호출 시 profileAdvice클래스의 abc()메소드가 호출.

<!-- 객체 생성 : 어노테이션 -->
<context:component-scan base-package="aop3"/>
<!-- Aop 설정 -->
<aop:aspectj-autoproxy/>

 

 

 

* 스프링 AOP에서 용어


 - Joinpoint : ‘클래스의 인스턴스 생성 시점’, ‘메소드 호출 시점’ 및 ‘예외 발생 시점’ 과 같이 어플리케이션을 실행할 때 특정 작업이 시작되는 시점을 의미.

 - Advice : 조인포인트에 삽입되어 동작할 수 있는 코드를 말함.

 - Pointcut : 여러 개의 조인포인트를 하나로 결합한(묶은) 것을 말함.

 - Advisor : 어드바이스와 포인트컷을 하나로 묶어 취급한 것을 말함.

 - Weaving : 어드바이스를 핵심 로직 코드에 삽입하는 것을 말함.

 - Target : 핵심 로직을 구현하는 클레스.

 - Aspect : 여러 객체에 공통으로 적용되는 공통 관점 사항을 말함.

 

 

1) AOP 구현

 - LogicInter

public interface LogicInter {
	void startProcess();
}

 

 - LogicImpl

@Service // @Component와 동일하지만 가독성을 위해 Service기능을 사용하면 @Service를 사용.
public class LogicImpl implements LogicInter{
	
	public LogicImpl() {
	}
	
	public void startProcess() {
		System.out.println("핵심 로직 수행");
	}
}

 

 - aop4.xml

<!-- 어노테이션을 사용하여 객체 생성 -->
<context:component-scan base-package="aop4"/>
<!-- aop를 사용하도록 설정 -->
<aop:aspectj-autoproxy/>

    <context:component-scan base-package="패키지명"/>
    <aop:aspectj-autoproxy/>

 

 - main

public static void main(String[] args) {
	ApplicationContext context = new ClassPathXmlApplicationContext("aop4.xml");
	LogicInter inter = (LogicInter)context.getBean("logicImpl");
	// getBean의 매개변수 : @객체 생성할 클래스명을 첫글자 소문자로 변경하여 생성. 
	inter.startProcess();
}

 

 - RunAspect

// 아이디가 같으면 핵심로직 수행, 다르면 수행하지않도록 구현.
@Component
@Aspect // 독립적으로 동작할 관심 로직 클래스에 사용
public class RunAspect {
	
	@Around("execution(public void startProcess())")
	// 핵심로직의 메소드를 선택. 해당메소드 호출시 관심 메소드 호출.
	//@Around는 핵심로직 실행 전/후 모두 기능을 추가할 수 있다.
	public Object trace(ProceedingJoinPoint joinPoint) throws Throwable{
		
		System.out.println("AOP 시작 : 핵심 로직 처리전 id 검증");
		System.out.print("input id : ");
		Scanner scanner = new Scanner(System.in);
		String id = scanner.nextLine();
		if(! id.equalsIgnoreCase("aa")) { //equalsIgnoreCase() 대소문자 구분하지않고 비교.
			System.out.println("id 불일치하여 작업을 종료합니다.");
			return null;
		}
		
		Object obj = joinPoint.proceed(); // 핵심 로직 수행.
		
		return obj;
	}
}

    @Component

    @Aspect

    @Around("excution(핵심 로직의 메소드)")

    public Object 관심메소드명(ProceedingJoinPoint joinPoint) throws Throwable{ .. }

    Object obj = joinPoint.proceed();

    str1.equalsIgnoreCase(str2)

 

 

 

 

+ Recent posts

1