Avatar billede kernelx Juniormester
15. november 2010 - 10:44 Der er 8 kommentarer og
1 løsning

Java EE 6 create custom scope

Hi,

jeg håber at denne kategori (j2ee) også må bruges til Java EE 6 spørgsmål.

på nettet finder jeg mange dokumenter som siger, at man kan defininere sine egne scopes med en annotation som er annoteret med @Scope.
Jeg har også fundet et eksempel et sted.

Men:
Et eller andet sted må der jo være en mulighed for at definiere, hvornår en ny defineret scope er aktiv og hvornår en scope context bliver destroyed igen.

Er der en, som kan give mig en god tutorial, som viser et eksempel, som definerer en ny scope og bruger denne nye scope i et eksempel?
Eller er der en som har lyst at give mig et eksempel her i denne thread?

Mange tak allerede i forvejen!
Avatar billede arne_v Ekspert
27. november 2010 - 23:11 #1

package test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.enterprise.context.NormalScope;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@NormalScope
public @interface MyScoped {
}



package test;

import java.lang.annotation.Annotation;
import java.util.Map;
import java.util.HashMap;

import javax.enterprise.inject.spi.Bean;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.Contextual;
import javax.enterprise.context.spi.CreationalContext;

public class MyContext implements Context {
    private Map<String,Object> cache = new HashMap<String,Object>();
    public <T> T get(Contextual<T> ctx) {
        return null;
    }
    public <T> T get(Contextual<T> ctx, CreationalContext<T> crectx) {
        String clz = ((Bean<T>)ctx).getBeanClass().getName();
        @SuppressWarnings("unchecked")
        T o = (T)cache.get(clz);
        if(o == null) {
            o = ctx.create(crectx);
            cache.put(clz, o);
        }
        return o;
    }
    public Class<? extends Annotation> getScope() {
        return MyScoped.class;
    }
    public boolean isActive() {
        return true;
    }
    public void reset() {
        cache.clear();
    }
}



package test;

import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterBeanDiscovery;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Extension;

public class MyContextExtension implements Extension {
    public void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager manager) {
        event.addContext(new MyContext());
    }
}



...
        <jar basedir="${bin}" includes="**/My*.class" destfile="${jar}">
            <service type="javax.enterprise.inject.spi.Extension" provider="test.MyContextExtension"/>
        </jar>
...



    @Inject
    private BeanManager bm;
    ...
            // MyScope is now out of scope !!
            ((MyContext)bm.getContext(MyScoped.class)).reset();



MyScoped er i scope indtil eksplicit smidt ud.
Avatar billede kernelx Juniormester
03. december 2010 - 08:37 #2
mange tusind tak!!!

husk at skrive et eller andet som svar
Avatar billede kernelx Juniormester
03. december 2010 - 20:23 #3
hvad betyder isActive?
hvad ville det have for konsekvenser, hvis isActiv ville returnere false?
Avatar billede arne_v Ekspert
03. december 2010 - 20:38 #4
Proev det.

Jeg formoder at den vil smide en exception med at der ikke er en aktiv context for den paagaeldende type.
Avatar billede arne_v Ekspert
03. december 2010 - 20:41 #5
Naar jeg kigger paa koden nu saa er jeg oevrigt lidt bange for at der er en resource laek.

crectx.release() boer kaldes naar man rydder op ellers er jeg bange for at containeren beholder en ref til alle de gamle objekter ogsaa efter reset.

MyContext get skal saa gemme crectx'erne for at kunne lave den oprydning.
Avatar billede arne_v Ekspert
03. december 2010 - 20:42 #6
og et svar
Avatar billede kernelx Juniormester
03. december 2010 - 20:43 #7
mange mange tak for svar!
jeg er lidt bange for, at du glemmer at skrive et eller andet som svar :-)
Avatar billede kernelx Juniormester
03. december 2010 - 20:44 #8
ok, du var hurtigere :-)
Avatar billede arne_v Ekspert
05. december 2010 - 20:32 #9
Så vidt jeg kan se lækker koden ikke ressourcer som den ser ud nu med JBoss AS 6.0 CR1, men jeg er ikke sikker på at specs garanterer dette.

Jeg har også noteret mig, at der heller ikke er nogen garanti for tilgangen til Context, så min Context klasse er ikke thread safe.

Så for en sikkerheds skyld:

package test;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.enterprise.inject.spi.Bean;
import javax.enterprise.context.spi.Context;
import javax.enterprise.context.spi.Contextual;
import javax.enterprise.context.spi.CreationalContext;

public class MyContext implements Context {
    private Map<String,Object> objcache = new HashMap<String,Object>();
    private List<CreationalContext> ctxcache = new ArrayList<CreationalContext>();
    public <T> T get(Contextual<T> ctx) {
        return null;
    }
    public <T> T get(Contextual<T> ctx, CreationalContext<T> crectx) {
        String clz = ((Bean<T>)ctx).getBeanClass().getName();
        @SuppressWarnings("unchecked")
        T o;
        synchronized(objcache) {
            o = (T)objcache.get(clz);
            if(o == null) {
                o = ctx.create(crectx);
                objcache.put(clz, o);
            }
            ctxcache.add(crectx);
        }
        return o;
    }
    public Class<? extends Annotation> getScope() {
        return MyScoped.class;
    }
    public boolean isActive() {
        return true;
    }
    public void reset() {
        synchronized(objcache) {
            objcache.clear();
            for(CreationalContext crectx : ctxcache) {
                crectx.release();
            }
        }
    }
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester