Java Spring AOP çalışmıyor

tensa_zangetsu

Centipat
Katılım
28 Ağustos 2023
Mesajlar
2.873
Çözümler
11
Arkadaşlar AspectJ adlı kütüphane kullanarak Spring'de basit bir Loglama özelliği yapıyordum ama bir türlü çalıştıramadım.
Öncelikle saçma sapan bir şekilde dağınık halde yazdığım için üzgünüm, belki bundan da çalışmyordur, kusura bakmayın.

Main metodu, App sınıfında.

Veri tabanından veri çekiyor, listeliyor falan buralar çalışıyor bir hata yada başka bir sorun belirtmiyor ama hiçbir şekilde,
LogDataBaseController sınıfındaki @After, @Before ile işaretlenmiş metotlar çalışmıyor.


DataBaseController sınıfı;
Java:
package controller;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;



import model.DataBase;
import model.Student;

@Component("dataBaseController")
@Aspect
public class DataBaseController {
 
    private Connection connect;

    @Autowired
    private DataBase dataBase;
 
 

    public void connectDB() {
        try {
            connect = DriverManager.getConnection(dataBase.getUrl(), dataBase.getUser(), dataBase.getPassword());
       
            System.out.println("Veri Tabanına bağlanıldı");
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            System.err.println("Veritabanına bağlanılamadı");
        }
    }
 
 
    public List<Student> moveList() {
   
        connectDB();
   
   
        List<Student> listStudent = new ArrayList<Student>();
        try {
       
            Statement stat = connect.createStatement();
            ResultSet res;
            res = stat.executeQuery("select no, name, surname from student");
       
            while(res.next()) {
                Student student = new Student();
           
                student.setName(res.getString("name"));
                student.setSurName(res.getString("surname"));
                student.setNo(res.getInt("no"));
                listStudent.add(student);
            }
       
        }catch(Exception e) {
            System.err.println("Hata 1 - Listeye eklenemedi");
        }
   
   
        return listStudent;
   
   
    }
 
 
    public DataBase getDataBase() {
        return dataBase;
    }
 
    public void setDataBase(DataBase dataBase) {
        this.dataBase = dataBase;
    }
}


LogDataBaseController sınıfı;
Java:
package model;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogDataBaseController {
 
    @Before("execution (* moveList(..))")
    public void listBefore() {
   
        System.out.println("Listeye veri ekleniyor");
    }
 

}


AppConfig Sınıfı;
Java:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

import model.DataBase;

@Configuration
@ComponentScan(basePackages = {"model" , "controller"})
@EnableAspectJAutoProxy (proxyTargetClass = true)
public class AppConfig {
 
 

}


App Sınıfı;


Java:
import java.util.List;



import org.springframework.context.ApplicationContext;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;



import controller.DataBaseController;

import controller.StudentController;

import model.DataBase;

import model.Student;



public class App {

    public static void main(String[] args) {





        ApplicationContext cac = new AnnotationConfigApplicationContext(AppConfig.class);

  

        DataBase dataBase = (DataBase) cac.getBean("dataBase");

  

        dataBase.setUser("root");

        dataBase.setUrl("jdbc:mysql://localhost:3306/personel");

        dataBase.setPassword("");

  

        DataBaseController dataBaseController = (DataBaseController) cac.getBean("dataBaseController");

  

        dataBaseController.connectDB();

  

        StudentController studentController = (StudentController) cac.getBean("studentController");

  

        studentController.setStudentList(dataBaseController.moveList());

  

        studentController.Listing();

  

  

    }

}
 
Son düzenleme:
İnternetten araştırdığım kadarıyla sizdeki eksiklik şurada:
Java:
@Before("execution (* moveList(..))")

moveList yerine bu metodun tam yolunu vermeniz gerekiyor diye düşünüyorum. Bir örnek olarak şu sitedekini paylaşayım:
Java:
@Before("execution(* com.howtodoinjava.core.aop.service.EmployeeService.*(..))")

Sizin yazmanız gereken, şöyle bir şey galiba:
Java:
@Before("execution (* com.[...].DataBaseController.moveList(..))")

[...] yazdığım yeri uygun şekilde tamamlamalısınız.
 
İnternetten araştırdığım kadarıyla sizdeki eksiklik şurada:
Java:
@Before("execution (* moveList(..))")

moveList yerine bu metodun tam yolunu vermeniz gerekiyor diye düşünüyorum. Bir örnek olarak şu sitedekini paylaşayım:


Sizin yazmanız gereken, şöyle bir şey galiba:
Java:
@Before("execution (* com.[...].DataBaseController.moveList(..))")

[...] yazdığım yeri uygun şekilde tamamlamalısınız.
Deneyip dönüş yapacağım hemen.
 
Diğer arkadaşın dediği package ismi vs. belirtmek sadece o package içinde moveList diye method varsa çalış demek, mevzu o değil yani.

Silmeyi unuttum oradan ama silip denemedim hiç.
Sorun bundan kaynaklı olabilir, databasecontroller @component, aspect olarak çalışmasını istediğin diğer class @Aspect olsun, springin kafası karışıyor muhtemelen.
 
Diğer arkadaşın dediği package ismi vs. belirtmek sadece o package içinde moveList diye method varsa çalış demek, mevzu o değil yani.


Sorun bundan kaynaklı olabilir, databasecontroller @component, aspect olarak çalışmasını istediğin diğer class @Aspect olsun, springin kafası karışıyor muhtemelen.
Ya aslında uçlar dediğimiz kısımlardan biri :D. Hiç tahmin etmezdim bunu. Aslında bunu Spring'e bildirmek gerek. Bence bunun da ayrılması gerek.
 
Aslında bunu Spring'e bildirmek gerek.
Böyle bir bilgiyi arasam bulamazdım hiç. Rastgele önüme çıktı.

Çalışma mantığını kafada canlandıracak kadar teorik bilgi gerekiyor, o zaman sorun şu olabilir bu olabilir diye fikir yürütebiliyorsunuz, ihtiyaç olan bilgiyi (yüzeysel değil de detaylı bilgi de olsa) bulmak da kolaylaşıyor o zaman.

"In Spring AOP, it is not possible to have aspects themselves be the target of advicefrom other aspects. The @Aspect annotation on a class marks it as an aspect, andhence excludes it from auto-proxying."

demiş spring, sizin kodunuzu görünce ben de @Aspect ile tanımlanmış ilk sınıfa diğer @Aspect ile tanımlı sınıftan advice eklenebilir mi, proxy düzgün oluşturabilir mi (yani spring aop çalışma mantığı bu, aop kodunu çalıştırmak dışında okuyarak elde edilecek teorik bilgi) diye şüphe etmiştim, çoklu proxy'yi handle edebilir mi acaba diye, sorun kaynağı muhtemelen budur dedimdi, spring aop dokümanında @Aspect ile alakalı bölümü biraz kurcaladım, böyle yazılmış, edemiyormuş.
 

Geri
Yukarı