Статьи

OSGI и Spring Dynamic Modules — Простой Привет, Мир

В этой позе мы рассмотрим первую реализацию, которую мы сделали с использованием OSGi, и будем использовать Spring Dynamic Modules для улучшения приложения.

Spring Dynamic Modules (Spring Dm) значительно упрощает разработку приложений на базе OSGi . При этом развертывание сервисов становится намного проще. Вы можете добавить сервисы, как и любые другие бобы Spring.

Итак, начнем с Spring dm.

Прежде всего, вам необходимо скачать Spring Dm Distribution . В этой статье я использовал дистрибутивы с зависимостями и буду использовать только эти библиотеки:

01
02
03
04
05
06
07
08
09
10
11
12
13
com.springsource.net.sf.cglib-2.1.3.jar
com.springsource.org.aopalliance-1.0.0.jar
log4j.osgi-1.2.15-SNAPSHOT.jar
com.springsource.slf4j.api-1.5.0.jar
com.springsource.slf4j.log4j-1.5.0.jar
com.springsource.slf4j.org.apache.commons.logging-1.5.0.jar
org.springframework.aop-2.5.6.SEC01.jar
org.springframework.beans-2.5.6.SEC01.jar
org.springframework.context-2.5.6.SEC01.jar
org.springframework.core-2.5.6.SEC01.jar
spring-osgi-core-1.2.1.jar
spring-osgi-extender-1.2.1.jar
spring-osgi-io-1.2.1.jar

Конечно, вы можете заменить библиотеки Spring 2.5.6 библиотеками Spring 3.0. Но для этой статьи Spring 2.5.6 будет достаточно.

Итак, начнем с пакета услуг. Если мы помним, этот пакет экспортировал один сервис:

1
2
3
4
5
package com.bw.osgi.provider.able;
  
public interface HelloWorldService {
    void hello();
}
01
02
03
04
05
06
07
08
09
10
package com.bw.osgi.provider.impl;
  
import com.bw.osgi.provider.able.HelloWorldService;
  
public class HelloWorldServiceImpl implements HelloWorldService {
    @Override
    public void hello(){
        System.out.println("Hello World !");
    }
}

Здесь нет никаких изменений. Теперь мы можем увидеть активатор:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.bw.osgi.provider;
  
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
  
import com.bw.osgi.provider.able.HelloWorldService;
import com.bw.osgi.provider.impl.HelloWorldServiceImpl;
  
public class ProviderActivator implements BundleActivator {
    private ServiceRegistration registration;
  
    @Override
    public void start(BundleContext bundleContext) throws Exception {
        registration = bundleContext.registerService(
                HelloWorldService.class.getName(),
                new HelloWorldServiceImpl(),
                null);
    }
  
    @Override
    public void stop(BundleContext bundleContext) throws Exception {
        registration.unregister();
    }
}

Итак, здесь мы сделаем все просто. Давайте удалим этот класс, это больше не полезно с Spring Dm.

Мы позволим Spring Dm экспортировать пакет для нас. Мы создадим контекст Spring для этого пакета. Нам просто нужно создать файл provider-context.xml в папке META-INF / spring . Это простой контекст в XML-файле, но мы используем новое пространство имен для регистрации службы: « http://www.springframework.org/schema/osgi «. Итак, начнем :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
  
    <bean id="helloWorldService" class="com.bw.osgi.provider.impl.HelloWorldServiceImpl"/>
  
    <osgi:service ref="helloWorldService" interface="com.bw.osgi.provider.able.HelloWorldService"/>
</beans>

Единственное, что специфично для OSGi — это объявление osgi: service. Эта строка указывает, что мы регистрируем helloWorldService в качестве службы OSGi, используя интерфейс HelloWorldService в качестве имени службы.

Если вы поместите файл контекста в папку META-INF / spring , он будет автоматически обнаружен Spring Extender и будет создан контекст приложения.

Теперь мы можем перейти к потребительской пачке. На первом этапе мы создали этого потребителя:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package com.bw.osgi.consumer;
  
import javax.swing.Timer;
  
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
  
import com.bw.osgi.provider.able.HelloWorldService;
  
public class HelloWorldConsumer implements ActionListener {
    private final HelloWorldService service;
    private final Timer timer;
  
    public HelloWorldConsumer(HelloWorldService service) {
        super();
  
        this.service = service;
  
        timer = new Timer(1000, this);
    }
  
    public void startTimer(){
        timer.start();
    }
  
    public void stopTimer() {
        timer.stop();
    }
  
    @Override
    public void actionPerformed(ActionEvent e) {
        service.hello();
    }
}

В настоящее время здесь нет никаких изменений. Вместо внедрения с помощью конструктора мы могли бы использовать аннотацию @Resource, но это не работает в Spring 2.5.6 и Spring Dm (но хорошо работает в Spring 3.0).

А теперь активатор:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.bw.osgi.consumer;
  
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
  
import com.bw.osgi.provider.able.HelloWorldService;
  
public class HelloWorldActivator implements BundleActivator {
    private HelloWorldConsumer consumer;
  
    @Override
    public void start(BundleContext bundleContext) throws Exception {
        ServiceReference reference = bundleContext.getServiceReference(HelloWorldService.class.getName());
  
        consumer = new HelloWorldConsumer((HelloWorldService) bundleContext.getService(reference));
        consumer.startTimer();
    }
  
    @Override
    public void stop(BundleContext bundleContext) throws Exception {
        consumer.stopTimer();
    }
}

Инъекция больше не нужна. Мы можем сохранить запуск таймера здесь, но еще раз, мы можем использовать функции инфраструктуры для запуска и остановки таймера. Итак, давайте удалим активатор и создадим контекст приложения, чтобы создать потребителя, запустить его автоматически и поместить в папку META-INF / spring :

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="UTF-8"?>
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
  
    <bean id="consumer" class="com.bw.osgi.consumer.HelloWorldConsumer" init-method="startTimer" destroy-method="stopTimer"
          lazy-init="false" >
        <constructor-arg ref="eventService"/>
    </bean>
  
    <osgi:reference id="eventService" interface="com.bw.osgi.provider.able.HelloWorldService"/>
</beans>

Мы использовали атрибуты init-method и destroy-method для запуска и остановки времени в фреймворке, и мы используем конструктор-arg, чтобы внедрить ссылку на сервис. Ссылка на сервис получается с использованием поля osgi: reference и с использованием интерфейса в качестве ключа к сервису.

Это все, что нам нужно сделать с этим комплектом. Намного проще, чем в первой версии, не так ли? И помимо упрощения, вы можете видеть, что источники не зависят ни от OSGi, ни от Spring Framework, это простая Java и это большое преимущество.

POM Maven такие же, как на первом этапе, за исключением того, что мы можем сократить зависимость от OSGI.

Провайдер:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="UTF-8"?>
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    <modelVersion>4.0.0</modelVersion>
    <groupId>OSGiDmHelloWorldProvider</groupId>
    <artifactId>OSGiDmHelloWorldProvider</artifactId>
    <version>1.0</version>
    <packaging>bundle</packaging>
  
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
  
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>OSGiDmHelloWorldProvider</Bundle-SymbolicName>
                        <Export-Package>com.bw.osgi.provider.able</Export-Package>
                        <Bundle-Vendor>Baptiste Wicht</Bundle-Vendor>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Потребитель:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="UTF-8"?>
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    <modelVersion>4.0.0</modelVersion>
    <groupId>OSGiDmHelloWorldConsumer</groupId>
    <artifactId>OSGiDmHelloWorldConsumer</artifactId>
    <version>1.0</version>
    <packaging>bundle</packaging>
  
    <dependencies>
        <dependency>
            <groupId>OSGiDmHelloWorldProvider</groupId>
            <artifactId>OSGiDmHelloWorldProvider</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>
  
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
  
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
                <extensions>true</extensions>
                <configuration>
                    <instructions>
                        <Bundle-SymbolicName>OSGiDmHelloWorldConsumer</Bundle-SymbolicName>
                        <Bundle-Vendor>Baptiste Wicht</Bundle-Vendor>
                    </instructions>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

И мы можем собрать два пакета, используя maven install. Итак, давайте проверим наши вещи в Феликсе:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
wichtounet@Linux-Desktop:~/Desktop/osgi/felix$ java -jar bin/felix.jar
_______________
Welcome to Apache Felix Gogo
 
g! install file:../com.springsource.slf4j.org.apache.commons.logging-1.5.0.jar
Bundle ID: 5
g! install file:../com.springsource.slf4j.log4j-1.5.0.jar
Bundle ID: 6
g! install file:../com.springsource.slf4j.api-1.5.0.jar
Bundle ID: 7
g! install file:../log4j.osgi-1.2.15-SNAPSHOT.jar
Bundle ID: 8
g! install file:../com.springsource.net.sf.cglib-2.1.3.jar
Bundle ID: 9
g! install file:../com.springsource.org.aopalliance-1.0.0.jar
Bundle ID: 10
g! install file:../org.springframework.core-2.5.6.SEC01.jar
Bundle ID: 11
g! install file:../org.springframework.context-2.5.6.SEC01.jar
Bundle ID: 12
g! install file:../org.springframework.beans-2.5.6.SEC01.jar
Bundle ID: 13
g! install file:../org.springframework.aop-2.5.6.SEC01.jar
Bundle ID: 14
g! install file:../spring-osgi-extender-1.2.1.jar
Bundle ID: 15
g! install file:../spring-osgi-core-1.2.1.jar
Bundle ID: 16
g! install file:../spring-osgi-io-1.2.1.jar
Bundle ID: 17
g! start 5 7 8 9 10 11 12 13 14 15 16 17
log4j:WARN No appenders could be found for logger (org.springframework.osgi.extender.internal.activator.ContextLoaderListener).
log4j:WARN Please initialize the log4j system properly.
g! install file:../OSGiDmHelloWorldProvider-1.0.jar
Bundle ID: 18
g! install file:../OSGiDmHelloWorldConsumer-1.0.jar
Bundle ID: 19
g! start 18
g! start 19
g! Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
Hello World !
stop 19
g!

Как видите, работает отлично!

В заключение, Spring Dm действительно облегчает разработку с OSGi. С Spring Dm вы также можете запускать связки. Он также позволяет создавать веб-пакеты и легко пользоваться услугами компендиума OSGi.

Вот источники двух проектов:

Вот непосредственно две сборочные банки:

И вот полная папка, включая Felix и Spring Dm: osgi-hello-world.tar.gz

Ссылка: OSGI и Spring Dynamic Modules — Simple Hello World от нашего партнера JCG Баптиста Вихта в

Статьи по Теме :