简体   繁体   中英

How to cast from super class to derived class in field injected by CDI?

I'm using JSF 2.1 with CDI and JBoss 7.1.1

Is it possible to inject with CDI in a super class variable principal and cast to derived class ? In example MyUserPrincipal is derived class. If I write @Inject Principal principal I know from debugging (and overloaded toString() method) that MyUserPrincipal proxy class will be injected in the variable principal . But I could not cast this instance to MyUserPrincipal instance.

Below my 2 attempts to solve the problem:

public class MyUserPrincipal implements Principal, Serializible{
   MyUserPrincipal (String name){
   }
   public myMethod() { }
}

//Attempt 1:
public class MyCdiClass2 implements Serializable{
   //MyUserPrincipal proxy instance will be injected. 
   @Inject Principal principal;      

   @PostConstruct init() {
       MyUserPrincipal myPrincipal = (MyUserPrincipal) pincipal;  //<--- Fails to cast! (b)
      myPrincipal.myMethod();
   }
}

//Attempt 2:
public class MyCdiClass1 implements Serializable{
   @Inject MyUserPrincipal myPrincipal; //<---- Fails to inject! (a)

   @PostConstruct init() {
       //do something with myPrincipal

   }
}

If you do not have a producer, what you're injecting is actually a proxy which extends the container provided principal. Two classes that implement the same interface are assignment compatible to a field whose type is that interface, but you cannot cast one as the other.

That said, it seems you want to override the built-in principal bean. As far as I know, you can only achieve that using alternatives prior to CDI 1.0, and also using decorators in CDI 1.1, see CDI-164 .

Alternatives example:

package com.example;

@Alternative
public class MyUserPrincipal implements Principal, Serializible {

    // ...

    @Override
    public String getName() {
        // ...
    }
}

// and beans.xml

<?xml version="1.0" encoding="UTF-8"?>

http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> com.example.MyUserPrincipal

Decorator example:

@Decorator
public class MyUserPrincipal implements Principal, Serializible {

    @Inject @Delegate private Principal delegate;

    // other methods

    @Override
    public String getName() {
        // simply delegate or extend
        return this.delegate.getName();
    }
}

// again plus appropriate beans.xml

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM