Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Spring AOP: не инициализируется GlobalAdvisorAdapt, не грузтися приложение на Spring 
V
    Опции темы
Pawl
Дата 3.11.2012, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 3
Всего: 28



Доброго времени суток,
вникаю в реализацию АОП в Spring, и пока плохо получается. Из разрозненных примеров, собранных на просторах интернет, собрал web-приложение, которое не работает: при загрузке вываливается ошибка - Error creating bean with name 'org.springframework.aop.config.internalAutoProxyCreator': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry
приведу исходники контроллера, аспекта и xml-конфига:
Код

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
                http://www.springframework.org/schema/aop
                http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
        
    <context:component-scan base-package="study.spring.controllers" />

    <aop:aspectj-autoproxy />
    <!-- описание класса аспекта-->
    <bean id="calc" class="study.spring.form.Calc" />

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver"
        p:prefix="/WEB-INF/views/"
        p:suffix=".jsp" />
</beans>

Код

package study.spring.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.validation.BindingResult;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import study.spring.form.*;

@Controller
public class LoginController {
    // класс аспекта
    @Autowired
    private Calc calc;
    private int i;

    @RequestMapping(method = RequestMethod.GET)
    public String showForm(Map model) {
        LoginForm loginForm = new LoginForm();
        model.put("loginForm", loginForm);
        return "loginform";
    }
     
    @RequestMapping(value = "loginform.html", method = RequestMethod.POST)
    public String processForm(LoginForm loginForm, BindingResult result)  throws Exception {
        // получаю из класса аспекта значение счетчика
        i = calc.getCount();
        LoginPasValidator validator = new LoginPasValidator(path);
        validator.validate(loginForm, result);

        if (result.hasErrors()) {
            return "loginform";
        }

        return "loginsuccess";
    }
}

Код

package study.spring.form;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class Calc {
    private int count;

    public int getCount() {
        return count;
    }
    // метод, который должен вызываться перед каждым вызовом метода processForm в
    // контроллере и увеличивать счетчик
    @Before("execution(* study.spring.controllers.LoginController.processForm(..))")
    public void setCount() {
        count++;
    }
}

Вот, прошу помощи, помогите разобраться, как правильно сконфигурировать файл настройки Spring, ну и вообще, где что не так. P. S. вроде, все нужные библиотеки подключены:  Spring.aop, aspectjweaver, aspectjrt и aspectjtools.
Огромное спасибо заранее!

Это сообщение отредактировал(а) Pawl - 4.11.2012, 00:21


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
Kircul
Дата 4.11.2012, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 20.2.2007

Репутация: 1
Всего: 7



Цитата(Pawl @  3.11.2012,  14:38 Найти цитируемый пост)
P. S. вроде, все нужные библиотеки подключены

Нет
Цитата(Pawl @  3.11.2012,  14:38 Найти цитируемый пост)
... nested exception is java.lang.NoClassDefFoundError: Could not initialize class org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry

PM   Вверх
Pawl
Дата 4.11.2012, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 3
Всего: 28



Цитата(Kircul @  4.11.2012,  11:07 Найти цитируемый пост)
Нет

Ок, подключил еще бибилиотеку aopalliance, после чего стала вылетать другая ошибка:
Код

org.springframework.beans.factory.BeanCreationException: Error creating bean with name
 'loginController': Injection of autowired dependencies failed; nested exception is 
org.springframework.beans.factory.BeanCreationException: Could not autowire field: private 
study.spring.form.Calc study.spring.controllers.LoginController.calc; nested exception is 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 
'study.spring.form.Calc#0' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]:
 Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize 
class net.sf.cglib.proxy.Enhancer

Погуглив, я нашел, что class net.sf.cglib.proxy.Enhancer находится в библиотеке cglib. Нашел, скачал, установил, проверил, что он там есть. Запустил - та же ошибка. Теперь-то чего ему не хватает? Класс ведь присутствует, а инициализировать его он почему-то не может!

Это сообщение отредактировал(а) Pawl - 4.11.2012, 12:45


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
Kircul
Дата 4.11.2012, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 166
Регистрация: 20.2.2007

Репутация: 1
Всего: 7



Не видя строки запуска приложения мало что могу сказать.
Тем не менее советую попробовать воспользоваться системой сборки с dependency manager'ом: Apach Ant + IvyMaven или Gradle.

Если всеже есть желание разобраться в том что же происходит, то советую прочитать это: http://skipy.ru/technics/likbez.html.  
PM   Вверх
Pawl
Дата 4.11.2012, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 3
Всего: 28



Цитата(Kircul @  4.11.2012,  14:28 Найти цитируемый пост)
Если всеже есть желание разобраться в том что же происходит, то советую прочитать это: http://skipy.ru/technics/likbez.html

Согласен, из моих предыдущих постов можно было подумать, что моя проблема в сборке. Для уточнения проблемы приведу предельно упрощенный код приложения (всего, не пугайтесь, не много  smile):
web.xml:
Код

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
</web-app>

index.jsp:
Код

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<% response.sendRedirect("page.htm"); %>

page.jsp:
Код

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java" %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Welcome to Spring Web MVC project</title>
    </head>
    <body>
        HELLO!
    </body>
</html>

Конфиг Spring (dispatcher-servlet.xml):
Код

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <aop:aspectj-autoproxy />
    <context:component-scan base-package="study.spring.controllers" />    
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/"
          p:suffix=".jsp" />
    <bean id="calc" class="study.spring.form.Calc" />
</beans>

Calc.java (мой аспект):
Код

package study.spring.form;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class Calc {
    @Before("execution(* *.doSmth(..))")
    public void setCount() {
        // do smth
    }
}

LoginController.java (мой контроллер):
Код

package study.spring.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping(value = "page.htm")
public class LoginController {   
    @RequestMapping(method = RequestMethod.GET)
    public String showForm() {      
        return "page";
    }
}

В таком виде, при наличии Spring'овых библиотек, а также aopalliance и aspectjweaver, приложение нормально разворачивается и запускается. Но дело в том, что аспект у меня накладывается на несуществующий метод doSmth. Если же поменять doSmth на метод showForm контроллера, то получаю следующую ошибку:
Код

org.springframework.beans.factory.BeanCreationException: Error creating bean with
 name 'loginController' defined in file [D:\Progs\EE\Spring\aopp\build\web\WEB-INF
\classes\study\spring\controllers\LoginController.class]: Initialization of bean failed; 
nested exception is java.lang.NoClassDefFoundError: Could not initialize class 
net.sf.cglib.proxy.Enhancer

Подозреваю, что дело тут кроется скорее в моем недопонимании Spring AOP, а не в незнании принципов сборки приложения  smile. А статья хорошая, читал ее раньше.


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
Pawl
Дата 4.11.2012, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 3
Всего: 28



Прошу прощения, что тема перестала соответствовать названию, но тут уже все коды - легче для понимания.
Удалось запустить приложение. Сделал следующее: добавил в web.xml параметры и слушателя контекста
Код

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

переписал класс аспекта:
Код

package study.spring.form;

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

@Component
@Aspect
public class Calc {
    private int count = 1;
    
    public int getCount() {
        return count;
    }
    
    @Before("execution(* *.showForm(..))")
    public void setCount() {
        ++count;
    }
}

создал applicationContext.xml 
Код

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd     
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
   <context:component-scan base-package="study.spring.form" />
   <aop:aspectj-autoproxy proxy-target-class="true" />
</beans>

а из dispatcher-servlet.xml убрал <aop:aspectj-autoproxy /> и <bean id="calc" class="study.spring.form.Calc" />.
Теперь что я хотел бы получить: в аспекте перед вызовом метода showForm контроллера должен сработать метод setCount и сделать count = 2.Затем я хочу всунуть этот count на форму:
Код

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import study.spring.form.Calc;

@Controller
@RequestMapping(value = "page.htm")
public class LoginController {
    // извлекаю из контекста приложения бин calc
    @Autowired
    private Calc calc;
    
    @RequestMapping(method = RequestMethod.GET)
    public String showForm(Map model) {
        // помещаю count на форму
        model.put("i", calc.getCount());
        return "page";
    }
}

код формы:
Код

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" language="java" %>
<%@ taglib prefix="core" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Welcome to Spring Web MVC project</title>
    </head>
    <body>
        <form:form action="page.htm" modelAttribute="i">
            <core:out value="${i}" />
        </form:form>
    </body>
</html>
 (с использованием jstl)
Как я все это понимаю: на странице должно отобразиться 2, т. к. setCount в аспекте, по идее, уже отработал и в контроллер попадает calc с count = 2. Это 2 и попадет на форму... Но я точно что-то не так понимаю, потому что на форму выводится 1.
Буду признателен, если наставите на путь истинный! smile 


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
Pawl
Дата 7.11.2012, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 649
Регистрация: 22.4.2008
Где: Витебск

Репутация: 3
Всего: 28



Решения для приложения Spring, сконфигурированного при помощи аннотаций не нашел. Решение для приложения, сконфигурированного через xml, описано тут


--------------------
В действительности всё совсем не так, как на самом деле
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0931 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.